Kubernetes
January 20, 2022

Настройка Spring Cloud Kubernetes Config

Наиболее распространённая практика конфигурирования приложений на Spring Boot заключается в написании специальных конфигурационных файлов, будь то application.properties, application.yml, application-dev.yml и тому подобное. Это очень удобно: меняешь параметр, перезапускаешь модуль, получаешь результат. А иногда и перезапускать не нужно, если приложение особым образом сконфигурировано. Но это только локально! А что если речь заходит про "облака"?

Допустим, у нас есть приложение, которое сконфигурировано таким образом, что его параметры в файле application.yml получают значения из переменных окружения среды в которой развёрнуто это приложение. Приложение у нас находится в OpenShift и у его контейнера заданы эти самые значения параметров окружения. Тогда, для того, чтобы изменить значения параметров в приложении, нам нужно зайти в OpenShift, зайти в контейнер и изменить значения нужных параметров. Pod перезапустится и приложение начнёт работать с новой конфигурацией.

Но есть ещё один удобный способ конфигурации приложения в облаке — Spring Cloud Kubernetes Config. Благодаря ему можно подгружать значения параметров application.{properties|yml} из ConfigMap или Secrets. То есть теперь для того, чтобы изменить какое-либо из значений параметров, вовсе не обязательно лезть в контейнер и менять значения параметров там — достаточно изменить их в соответствующей ConfigMap и значение автоматически обновится в приложении. И да, вам даже не придётся его перезапускать!

Но теперь обо всём поподробнее.

Важный момент перед стартом

Несмотря на то, что текущая реализация Spring Cloud Kubernetes Config работает без ошибок, в официальной документации она отмечена как deprecated начиная с релиза Spring Cloud 2020.0. Взамен ей предлагается использовать spring-cloud-kubernetes-configuration-watcher.

@Deprecated

Configuration Watcher не так прост для запуска, как Spring Cloud Kubernetes Config, так как предполагает, что в OpenShift (Kubernetes) будет развёрнуто специальное приложение, которое будет отслеживать изменения в конфигурации ConfigMap и автоматически обновлять контекст соответствующего ему приложения.

Ключевые особенности Spring Cloud Kubernetes Config

Если в openshift.yml описан ConfigMap для модуля/приложения, то:

  • можно не задавать env секцию с переменными внутри openshift.yml (deployment descriptor)
  • можно не задавать параметры в application.yml файле
  • можно "на горячую" менять значения параметров в ConfigMap и получать мгновенное обновление в рабочем приложении без его перезапуска (добавление, изменение, удаление параметров)

Подключение в приложении

Для того, чтобы начать использовать Spring Cloud Kubernetes Config в своём приложении необходимо выполнить следующее:

1. Подключить 2 зависимости

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2. Добавить следующие свойства в application.{properties|yml}.

spring:
    application:
        name: application-name
    cloud:
        kubernetes:
            reload:
                enabled: true
                mode: event
 
management:
  endpoints:
    web:
      exposure:
        include: restart

3. Описать секцию ConfigMap в openshift.yml (deployment descriptor).

- apiVersion: v1
  kind: ConfigMap
  metadata:
    name: application-name
  data:
    sample.message: "This message is from ConfigMap in openshift.yml"

ВАЖНО: имя ConfigMap должно совпадать со значением параметра spring.application.name.

Если необходимо задать модулю другой ConfigMap, с именем отличным от spring.application.name, необходимо создать файл bootstrap.yml и добавить параметр spring.cloud.kubernetes.config.name (bootstrap.yml располагается рядом с application.yml).

4. Со стороны приложения вынести необходимые параметры в отдельный bean и отметить аннотациями @Configuration и @ConfigurationProperties/@RefreshScope (@ConfigurationProperties/@RefreshScope нужны для hot reload – об этом гласит документация).

@Configuration
@ConfigurationProperties(prefix = "sample")
public class DynamicProps {
 
    private String message = "Message from Application!";
 
}

5. После этого приложение можно разворачивать в облаке. И менять значения параметров на лету!

Как происходит обновление

За это отвечает параметр spring.cloud.kubernetes.reload.mode. Возможны 2 значения: event или polling.

  • Event (default) - отслеживание изменений в ConfigMap или Secrets через Kubernetes API (web socket).
    ВАЖНО: сервисный аккаунт должен иметь роль view
  • Polling - периодическое пересоздание конфигурации из ConfigMap или Secret (по умолчанию – 15 секунд)
    ВАЖНО: сервисный аккаунт должен иметь роль view

Описание ConfigMap

ConfigMap поддерживает как задание каждого параметра отдельно, так и задание параметров в виде целого файла application.{properties|yml}.

- apiVersion: v1
kind: ConfigMap
metadata:
  name: application-name
data:
  application.yml: |-
    pool:
      size:
        core: 1
        max:16

Заключение

Лично мне этот функционал понравился. Несмотря на то, что он @Deprecated и требуется небольшая настройка сервисной учётной записи со стороны кластера OpenShift/Kubernetes, менять значения параметров на лету очень удобно. Самый важный момент на мой взгляд заключается в том, что приложение не перестаёт работать и для конечного пользователя все эти манипуляции с параметрами могут остаться незамеченными.

Пользовались ли вы чем-то подобным? Понравился ли вам этот функционал? Поделитесь опытом!