Статьи по Spring Cloud

Чтение данных из configmap kubernetes с помощью spring

Kubernetes становится все более популярным средством развертывания приложений, особенно в архитектурах микросервисов.


С другой стороны, что касается Java-приложений, написанных с использованием Spring Boot, то от архитектуры Netflix практически отказались в пользу решений, которые напрямую используют потенциал Kubernetes, например, для создания сервисов, управления конфигурацией и т.д..

Spring следует этой тенденции, создав специальный проект: “Spring Cloud Kubernetes”.

В этой статье мы рассмотрим, как использовать его для чтения конфигураций непосредственно из ConfigMap. Решение, которое, как уже упоминалось, позволяет нам в полной мере использовать возможности Kubernetes и управлять горячими изменениями данных

Зависимости

Давайте начнем с установки необходимых зависимостей Maven:

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR8</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-kubernetes-dependencies</artifactId> <version>1.1.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- needed for spring kubernetes config reloads --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- spring cloud kubernetes config server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-config</artifactId> </dependency> </dependencies>
Code language: HTML, XML (xml)

Конфигурация

Инициализация значений осуществляется Spring в bootstrap, поэтому вам необходимо определить конфигурацию для доступа к ConfigMap(ам) в файле bootstrap.yaml.
Давайте рассмотрим общую конфигурацию:

spring: application: name: cloud-k8s-app cloud: kubernetes: config: # not needed if spring.application.name is equal to configmap metadata name name: default-name # ConfigMap metadata name namespace: default-namespace sources: # configure this to load from more than one ConfigMap # Spring Cloud Kubernetes looks up a ConfigMap named c1 in namespace default-namespace - name: c1 # Spring Cloud Kubernetes looks up a ConfigMap named default-name in whatever namespace n2 - namespace: n2 # Spring Cloud Kubernetes looks up a ConfigMap named c3 in namespace n3 - namespace: n3 name: c3
Code language: PHP (php)

Вся часть spring.cloud.kubernetes не нужна, если значение spring.application.name равно названию метаданных ConfigMap.

Часть spring.cloud.kubernetes.config.sources необходима, если вам нужно подключиться к большему количеству ConfigMaps, в противном случае вам просто нужно поместить значение имени метаданных в spring.cloud.kubernetes.config.name.

Пример

Сейчас мы рассмотрим пример, в котором мы будем считывать значения из двух отдельных ConfigMaps, определение которых мы покажем ниже:

apiVersion: v1 kind: ConfigMap metadata: name: k8s-demo-configmap data: application.properties: |- greeting.message=Hello from --- apiVersion: v1 kind: ConfigMap metadata: name: k8s-demo-custom-configmap data: custom-conf.properties: |- custom.name=K8s
Code language: JavaScript (javascript)

далее файл bootstrap.yaml со ссылками на ConfigMaps для чтения значений из них:

spring: application: name: k8s-demo cloud: kubernetes: reload: enabled: true mode: event strategy: refresh config: namespace: default sources: - name: k8s-demo-configmap - name: k8s-demo-custom-configmap
Code language: JavaScript (javascript)

Ниже приведены два класса, которые отображают через аннотацию @ConfigurationProperties две ConfigMaps:

import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "greeting") public class GreetingConfig { private String message = "Hi from"; }
Code language: JavaScript (javascript)
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "custom") public class CustomConfig { private String name = "Spring"; }
Code language: JavaScript (javascript)

На этом этапе мы определяем простой контроллер, в котором мы будем использовать два класса, управляющие конфигурациями, для чтения значений, взятых из двух ConfigMaps.

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class K8sDemoController { @Autowired private GreetingConfig config; @Autowired private CustomConfig customConfig; @GetMapping(value = "/hello") public String hello() { return config.getMessage() + " " + customConfig.getName(); } }
Code language: CSS (css)

Вызов метода GET /hello отобразит строку “Hello from K8S”.

С конфигурацией, определенной в файле bootstrap.yaml, если мы изменим значение в ConfigMap, оно будет автоматически обновлено Spring и станет доступно во время выполнения.

В дополнение к использованию PropertySources, как это сделано в примере, вы можете получать значения из ConfigMap непосредственно из Spring bean Environment. Spring помещает все значения, считанные из всех ConfigMaps, в свой экземпляр Enviroment, к которому вы можете получить доступ, сделав его @Autowired в вашем bean.

ВНИМАНИЕ: Механизм reload не работает, если вы читаете значения из ConfigMap с помощью аннотации @Value, поскольку они внедряются в экземпляр bean при загрузке.

Reload

Существуют различные режимы и стратегии для обработки перезагрузки значений из ConfigMap.

В основном, Spring предлагает 3 режима обновления (refresh, restart_context и shutdown) и две стратегии (event или polling). Подробности см. в официальной документации.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *