Полное руководство по Spring Cloud Config Server


Обзор Spring Cloud Config Server

Конфиг-сервер Spring Cloud — это REST-приложение, построенное на базе Spring Boot. Основная цель конфигурационного сервера — хранить конфигурации для всех сервисов в приложении (подумайте о микросервисах). Таким образом, каждому сервису не нужно хранить свои конфигурации. Им просто нужно указать на сервер конфигурации, чтобы получить свои конфигурации.

Spring Cloud Config Server может работать с различными технологиями для доставки конфигураций безопасным способом, такими как HashiCorp Vault, Git или файловая система (менее безопасная, не подходит для большинства производственных сред).
Давайте начнем с примера.

Быстрый старт Spring Cloud Config Server

Допустим, мы создаем микросервисное приложение для сети ресторанов. Один из сервисов называется cook service. Все, что он делает, это сообщает о количестве поваров, доступных во всей сети. Для простоты мы создадим приложение Spring Boot с одним контроллером, как показано ниже:

package com.datmt.springcloud.cookservice.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/")
public class CookController {


    @Value("${cook.count}")
    int cookCount;

    @GetMapping
    public String cook() {

        return "Cook count: " + cookCount; 

    }

}
Вход в полноэкранный режим Выход из полноэкранного режима

Как вы можете видеть, эта служба получает количество поваров в переменной свойств приложения под названием cook.count. Обычно мы задаем такие свойства в файле application.properties сервиса. Однако сегодня мы получим их из другого места: из сервера конфигурации Spring Cloud!
Существует множество способов определения конфигураций для сервисов в config-сервере (о которых мы узнаем позже). В этом разделе мы будем считывать конфигурацию из файловой системы.
Давайте посмотрим на конфигурацию нашего конфигурационного сервера Spring cloud:
Обратим внимание на последние 2 строки этого конфиг-файла. В строке 3 мы указали активный профиль для сканирования конфигурационного файла, который является родным. Это означает, что конфигурационный сервер Spring cloud будет сканировать файловую систему. В строке 4 указывается точное место для поиска. Classpath ссылается на каталог resources в нашем проекте:

В файлах cook-service*.properties есть один параметр, который имеет разные значения для разных сред:

В папке config есть три файла для сервиса cook. Почему эти файлы названы именно так? По соглашению, конфигурационные файлы для сервисов имеют такой формат: servicename-env.yaml или servicename-env.properties.
Это означает, что имя сервиса здесь должно совпадать с именем в файле application.properties сервиса cook.
Конфигурационный файл службы cook:

server.port=9977
spring.application.name=cook-service
spring.profiles.active=dev
spring.cloud.config.uri=http://localhost:9988
spring.config.import=optional:configserver:http://localhost:9988
Вход в полноэкранный режим Выйти из полноэкранного режима

Как вы можете видеть, в строке 2 мы назвали службу как cook-service. В строке 3 указан активный профиль, которым является dev. Это означает, что конфигурации для сервиса cook будут считываться из файла config/cook-service-dev.properties на сервере конфигурации. Если этот файл недоступен, будет использовано содержимое файла config/cook-service.properties.
Давайте запустим сервер конфигурации и посмотрим, что у нас есть:




Как вы можете видеть, URL конфигурации для профилей dev и prod включает конфигурации по умолчанию. Для несуществующего профиля будет использоваться конфигурация по умолчанию.
Теперь давайте запустим службу cook и посмотрим, сможет ли она получить нужную конфигурацию. Помните, что активным профилем является dev, поэтому мы ожидаем увидеть число 190:

Если мы изменим активный профиль на prod

server.port=9977
spring.application.name=cook-service
spring.profiles.active=prod
Вход в полноэкранный режим Выйти из полноэкранного режима

и перезагрузим службу cook, результат изменится:

Как вы можете видеть, мы успешно получили конфигурацию для службы cook с сервера config.
В следующем разделе мы попробуем перезагрузить конфигурацию при появлении обновлений на сервере config без перезагрузки службы cook.

Обновление конфигурации с помощью Actuator

Если на сервере конфигурации произошли изменения, как обновить службу cook, чтобы она получила правильные значения без перезапуска?
Spring Actuator — вот ответ.
В файле pom.xml добавьте Spring Actuator в качестве зависимости:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

      <!-- Omit other dependencies -->
    </dependencies>
Вход в полноэкранный режим Выйти из полноэкранного режима

В файле application.properties добавьте следующую строку:

management.endpoints.web.exposure.include=refresh
Ввести полноэкранный режим Выйти из полноэкранного режима

В контроллере добавьте аннотацию @RefreshScrope к классу:

package com.datmt.springcloud.cookservice.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/")
@RefreshScope
public class CookController {


    @Value("${cook.count}")
    int cookCount;

    @GetMapping
    public String cook() {

        return "Cook count: " + cookCount;  

    }

}
Вход в полноэкранный режим Выйти из полноэкранного режима

Добавив эти конфигурации, мы теперь можем вызывать службу cook по адресу /actuator/refresh для запроса обновления.
Например, для текущей запущенной среды (prod) мы изменим значение 4000 на 5000, а затем отправим следующий запрос:

Как вы можете видеть, сервис отвечает обратно с измененным конфигом.
Если мы перезагрузим службу cook сейчас, значение должно обновиться.

Настройка сервера Spring Cloud Config Server с помощью Git

Давайте узнаем, как можно использовать git для хранения ваших конфигураций и позволить серверу конфигурации извлекать данные и передавать их другим сервисам.

Использование публичного Git

Допустим, у нас есть репозиторий на GitHub, хранящий файлы конфигурации следующим образом:

Содержимое этих файлов точно такое же, как у нас на локальной машине. Давайте настроим сервер config на использование git.
Конфигурация довольно проста, вам нужно только внести эти изменения в файл application.properties на сервере конфигурации:

server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/quick-samples.git
spring.cloud.config.server.git.search-paths=config-server/config
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание на строки под номерами 3, 5 и 6. В строке 3 мы добавили git в качестве активного профиля, не удаляя родную опцию.
Вы можете задаться вопросом, как сервер config выбирает, какой профиль использовать? Ответ — последний в списке.
В строке 5 мы указываем на репозиторий Git.
В строке 6 мы указываем серверу конфигурации путь к файлам конфигурации.
Давайте перезапустим сервер конфигурации и посмотрим, сможет ли он прочитать конфигурацию:

Как вы можете видеть, сервер конфигурации смог прочитать конфигурации из git без проблем.
Давайте изменим значение на git и посмотрим, обновится ли вывод. Допустим, мы изменим значение cook.count с 5000 на 3000:

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

Разве это не потрясающе? Конечно! Но кто будет хранить такие конфиденциальные данные, как конфигурация, в публичном git? Давайте добавим аутентификацию, не так ли?

Добавление аутентификации Git для безопасности

Давайте переключим git-репозиторий на приватный. Теперь конфигурация выглядит следующим образом:

server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/Quick-Sample-private.git
spring.cloud.config.server.git.search-paths=config-server/config
Вход в полноэкранный режим Выход из полноэкранного режима

Если мы сейчас запустим службу config и посетим URL-адрес конфигурации службы cook, мы увидим страницу ошибки:

Это происходит потому, что сервер конфигурации не может прочитать файлы с GitHub, так как репозиторий является частным.
Как мы можем настроить его так, чтобы сервер конфигурации мог читать данные? Мы будем использовать персональный токен доступа GitHub!
Вы можете следовать руководству здесь, чтобы создать его: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token.
После создания токена мы поместим его данные в файл application.properties сервера конфигурации

server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/Quick-Sample-private.git
spring.cloud.config.server.git.search-paths=config-server/config
spring.cloud.config.server.git.username=my_temp_access_token
spring.cloud.config.server.git.password=ghp_D6AlGb0f9CY......D5XG0UqzJB
Вход в полноэкранный режим Выйти из полноэкранного режима

Как вы можете видеть в строках 7 и 8, необходимы имя пользователя и пароль. Пароль — это, очевидно, токен доступа. Имя пользователя — это имя маркера.
Теперь, если мы перезагрузим сервер конфигурации Spring cloud, мы снова сможем увидеть настройки:

Включить шифрование конфигурации для безопасности

До сих пор все конфигурации хранились в открытом виде. Это не самая лучшая практика.
Давайте добавим некоторый уровень безопасности, включив шифрование.
Spring cloud config server поддерживает симметричное и асимметричное шифрование. В этом посте мы будем реализовывать симметричное шифрование.
Давайте добавим параметры шифрования в файл application.properties сервера конфигурации:

server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/quick-samples.git
spring.cloud.config.server.git.search-paths=config-server/config
encrypt.key=SUPER_SECRET_ENCRYPT_KEY
Войти в полноэкранный режим Выйти из полноэкранного режима

В строке 7 мы помещаем настройки шифрования с ключом шифрования. В производственных настройках это плохая практика. Вы должны, по крайней мере, хранить ключ шифрования как переменную окружения, чтобы он не был открыт в исходном коде.
С этими новыми настройками мы можем отправить POST-запрос на сервер конфигурации /encrypt для шифрования данных. Например, если мы хотим зашифровать число 5000, запрос должен выглядеть следующим образом:

curl -X POST -H "Content-Type: text/plain" http://localhost:9988/encrypt -d=5000
Войти в полноэкранный режим Выйти из полноэкранного режима

Вот выходной результат:

Теперь давайте поместим это значение в наш git:

Заключение

В этом посте мы узнали, как использовать конфигурационный сервер Spring cloud для централизации конфигураций для всех других сервисов. Это универсальное решение, поддерживающее множество механизмов хранения и управления данными, таких как файловая система, git, HashiCorp Vault, JDBC.

Оцените статью
devanswers.ru
Добавить комментарий