1. Обзор
Когда мы создаем решение для микросервисов, оба Spring Cloud и Kubernetes являются оптимальными решениями, поскольку они предоставляют компоненты для решения наиболее распространенных проблем. Однако, если мы решим выбрать Kubernetes в качестве основного менеджера контейнеров и платформы развертывания для нашего решения, мы все равно сможем использовать интересные функции Spring Cloud в основном через проект Spring Cloud Kubernetes .
Этот относительно новый проект, несомненно, обеспечивает легкую интеграцию с Kubernetes для Spring Boot приложений. Перед запуском может быть полезно посмотреть, как развернуть приложение Spring Boot на Minicube , локальной среде Kubernetes .
В этом уроке мы рассмотрим:
- Установите Minitube на нашу локальную машину
- Разработайте пример архитектуры микросервисов с двумя независимыми приложениями Spring Boot, взаимодействующими через REST
- Настройка приложения в кластере с одним узлом с помощью мини-куба
- Разверните приложение с помощью YAML конфигурационных файлов
2. Сценарий
В нашем примере мы используем сценарий, когда турагенты предлагают различные предложения клиентам, которые время от времени будут запрашивать услуги турагентов. Мы используем его для демонстрации:
- обнаружение служб через Spring Cloud Kubernetes
- управление конфигурацией и внедрение конфигурационных карт и секретов Kubernetes в модули приложений с помощью Spring Cloud Kubernetes Config
- балансировка нагрузки использование ленты Spring Cloud Kubernetes
3. Настройка среды
Прежде всего, нам нужно установить Minitube на нашей локальной машине и предпочтительно драйвер виртуальной машины, такой как VirtualBox . Также рекомендуется ознакомиться с Kubernetes и его основными функциями, прежде чем следовать этой настройке среды.
Давайте запустим локальный одноузловой кластер Kubernetes:
minikube start --vm-driver=virtualbox
Эта команда создает виртуальную машину, которая запускает кластер Mini kube с помощью драйвера VirtualBox. Контекст по умолчанию в kubectl теперь будет minicube . Однако, чтобы иметь возможность переключаться между контекстами, мы используем:
kubectl config use-context minikube
После запуска Minicube мы можем подключиться к панели мониторинга Kubernetes , чтобы легко получить доступ к журналам и отслеживать наши службы, модули, конфигурационные карты и секреты:
minikube dashboard
3.1. Развертывание
Во-первых, давайте возьмем наш пример из GitHub .
На данный момент мы можем либо запустить “deployment-travel-client.sh” скрипт из родительской папки или же выполняйте каждую инструкцию одну за другой, чтобы получить хорошее представление о процедуре:
### build the repository mvn clean install ### set docker env eval $(minikube docker-env) ### build the docker images on minikube cd travel-agency-service docker build -t travel-agency-service . cd ../client-service docker build -t client-service . cd .. ### secret and mongodb kubectl delete -f travel-agency-service/secret.yaml kubectl delete -f travel-agency-service/mongo-deployment.yaml kubectl create -f travel-agency-service/secret.yaml kubectl create -f travel-agency-service/mongo-deployment.yaml ### travel-agency-service kubectl delete -f travel-agency-service/travel-agency-deployment.yaml kubectl create -f travel-agency-service/travel-agency-deployment.yaml ### client-service kubectl delete configmap client-service kubectl delete -f client-service/client-service-deployment.yaml kubectl create -f client-service/client-config.yaml kubectl create -f client-service/client-service-deployment.yaml # Check that the pods are running kubectl get pods
4. Обнаружение служб
Этот проект предоставляет нам реализацию интерфейса Service Discovery в Kubernetes. В среде микросервисов обычно существует несколько модулей, работающих с одной и той же службой. Kubernetes предоставляет службу в виде набора конечных точек , которые могут быть извлечены и достигнуты из приложения Spring Boot, работающего в модуле в том же кластере Kubernetes.
Например, в нашем примере у нас есть несколько реплик службы турагентства, доступ к которой осуществляется из нашей клиентской службы как http://travel-agency-service:8080 . Однако это внутренне приведет к доступу к различным блокам, таким как travel-agency-service-7c9cfff655-4hxnp .
Лента Spring Cloud Kubernetes использует эту функцию для балансировки нагрузки между различными конечными точками службы.
Мы можем легко использовать обнаружение служб, добавив spring-cloud-starter-kubernetes зависимость от нашего клиентского приложения:
org.springframework.cloud spring-cloud-starter-kubernetes
Кроме того, мы должны добавить @EnableDiscoveryClient и внедрить клиент Discovery в контроллер клиента с помощью @Autowired в нашем классе:
@SpringBootApplication @EnableDiscoveryClient public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@RestController public class ClientController { @Autowired private DiscoveryClient discoveryClient; }
5. Карты конфигурации
Как правило, микросервисы требуют некоторого управления конфигурацией . Например, в приложениях Spring Cloud мы будем использовать сервер конфигурации Spring Cloud.
Однако мы можем достичь этого с помощью ConfigMaps , предоставленных Kubernetes, при условии, что мы намерены использовать его только для конфиденциальной, незашифрованной информации. В качестве альтернативы, если информация, которой мы хотим поделиться, является конфиденциальной, мы должны использовать Secrets вместо этого.
В нашем примере мы используем карты конфигурации в приложении client-service Spring Boot. Давайте создадим client-config. файл yaml для определения конфигурационной карты клиент-службы :
apiVersion: v1 by d kind: ConfigMap metadata: name: client-service data: application.properties: |- bean.message=Testing reload! Message from backend is: %s
Services : %s
Важно, чтобы имя конфигурационной карты совпадало с именем приложения , указанным в файле “application.properties”. В данном случае это клиент-сервис . Затем мы должны создать карту конфигурации для клиент-сервис на Kubernetes:
kubectl create -f client-config.yaml
Теперь давайте создадим класс конфигурации ClientConfig с @Configuration и @ConfigurationProperties и введем в ClientController :
@Configuration @ConfigurationProperties(prefix = "bean") public class ClientConfig { private String message = "Message from backend is: %s
Services : %s"; // getters and setters }
@RestController public class ClientController { @Autowired private ClientConfig config; @GetMapping public String load() { return String.format(config.getMessage(), "", ""); } }
Если мы не указываем карту конфигурации, то мы должны ожидать увидеть сообщение по умолчанию, которое задано в классе. Однако, когда мы создаем карту конфигурации, это сообщение по умолчанию переопределяется этим свойством.
Кроме того, каждый раз, когда мы решаем обновить карту конфигурации, сообщение на странице изменяется соответствующим образом:
kubectl edit configmap client-service
6. Секреты
Давайте посмотрим, как работают Секреты , изучив спецификацию параметров подключения MongoDB в нашем примере. Мы собираемся создать переменные среды в Kubernetes, которые затем будут введены в приложение Spring Boot.
6.1. Создайте секрет
Первым шагом является создание секрета.yaml файл, кодирующий имя пользователя и пароль в Base64 :
apiVersion: v1 kind: Secret metadata: name: db-secret data: username: dXNlcg== password: cDQ1NXcwcmQ=
Давайте применим секретную конфигурацию к кластеру Kubernetes:
kubectl apply -f secret.yaml
6.2. Создайте службу MongoDB
Теперь мы должны создать службу MongoDB и развертывание travel-agency-deployment.yaml файл. В частности, в части развертывания мы будем использовать Секретные имя пользователя и пароль , которые мы определили ранее:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mongo spec: replicas: 1 template: metadata: labels: service: mongo name: mongodb-service spec: containers: - args: - mongod - --smallfiles image: mongo:latest name: mongo env: - name: MONGO_INITDB_ROOT_USERNAME valueFrom: secretKeyRef: name: db-secret key: username - name: MONGO_INITDB_ROOT_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password
По умолчанию mongo:latest образ создаст пользователя с именем пользователя и паролем в базе данных с именем admin.
6.3. Настройка MongoDB на сервисе Туристического агентства
Важно обновить свойства приложения, чтобы добавить информацию, связанную с базой данных. Хотя мы можем свободно указать имя базы данных admin , здесь мы скрываем наиболее конфиденциальную информацию, такую как имя пользователя и пароль :
spring.cloud.kubernetes.reload.enabled=true spring.cloud.kubernetes.secrets.name=db-secret spring.data.mongodb.host=mongodb-service spring.data.mongodb.port=27017 spring.data.mongodb.database=admin spring.data.mongodb.username=${MONGO_USERNAME} spring.data.mongodb.password=${MONGO_PASSWORD}
Теперь давайте взглянем на наш файл travel-agency-deployment property, чтобы обновить службы и развертывания, указав имя пользователя и пароль, необходимые для подключения к mongodb-service .
Вот соответствующий раздел файла с частью, связанной с подключением MongoDB:
env: - name: MONGO_USERNAME valueFrom: secretKeyRef: name: db-secret key: username - name: MONGO_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password
7. Связь с лентой
В среде микросервисов нам обычно нужен список модулей, в которых реплицируется наша служба, для выполнения балансировки нагрузки. Это достигается с помощью механизма, предоставляемого лентой Spring Cloud Kubernetes. Этот механизм может автоматически обнаруживать и достигать всех конечных точек определенной службы , а затем заполняет ленту Список серверов информацией о конечных точках.
Давайте начнем с добавления spring-cloud-starter-kubernetes-ribbon зависимости в наш клиент-сервис pom.xml файл:
org.springframework.cloud spring-cloud-starter-kubernetes-ribbon
Следующий шаг-добавить аннотацию @RibbonClient в наше клиент-сервис приложение:
@RibbonClient(name = "travel-agency-service")
Когда список конечных точек заполнен, клиент Kubernetes будет искать зарегистрированные конечные точки, находящиеся в текущем пространстве имен/проекте, соответствующем имени службы, определенному с помощью аннотации @RibbonClient .
Нам также необходимо включить ленточный клиент в свойствах приложения:
ribbon.http.client.enabled=true
8. Дополнительные функции
8.1. Истрикс
Hystrix помогает в создании отказоустойчивого и устойчивого приложения. Его основные цели-быстрое и быстрое восстановление.
В частности, в нашем примере мы используем Hystrix для реализации шаблона автоматического выключателя на клиент-сервер , аннотируя класс приложения Spring Boot с помощью @EnableCircuitBreaker .
Кроме того, мы используем резервную функциональность, аннотируя метод Travel Agency Service.get Deals() с @HystrixCommand() . Это означает, что в случае резервного копирования будет вызван getFallBackName() и будет возвращено сообщение “Запасной вариант”:
@HystrixCommand(fallbackMethod = "getFallbackName", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) public String getDeals() { return this.restTemplate.getForObject("http://travel-agency-service:8080/deals", String.class); } private String getFallbackName() { return "Fallback"; }
8.2. Индикатор Состояния Стручка
Мы можем воспользоваться преимуществами Spring Boot Индикатор работоспособности и Привод пружинной загрузки , чтобы предоставить пользователю информацию, связанную со здоровьем.
В частности, индикатор здоровья Kubernetes обеспечивает:
- название стручка
- IP-адрес
- пространство имен
- учетная запись службы
- имя узла
- флаг, указывающий, является ли приложение Spring Boot внутренним или внешним по отношению к Kubernetes
9. Заключение
В этой статье мы подробно рассмотрим проект Spring Cloud Kubernetes.
Так почему же мы должны его использовать? Если мы болеем за Kubernetes как платформу микросервисов, но по-прежнему ценим возможности Spring Cloud, то Spring Cloud Kubernetes дает нам лучшее из обоих миров.
Полный исходный код примера доступен на GitHub .