Spring Boot приложение в Kubernetes с Postgresql и Loki

от автора

Тема развертывания Spring Boot приложения в Kubernetes кластере уже не новая и на многих ресурсах, включая данный , написано немало уже статей с примерами. Сегодня я бы хотел рассказать не только развертывании самого приложения ,но и о сопутствующих сервисах ,а именно : база данных, балансировщик нагрузки ,а также система сбора и агрегирования логов.

Более подробно о всех компонентах :

  1. Spring Boot приложение, использующее в качестве БД PostgreSQL

  2. Docker образ сервера базы данных

  3. Docker Grafana (dashboard для отображения логов)

  4. Docker образ Loki(система сбора логов)

  5. Promtail (агент для отсылки логов в Loki).

    Kubernetes cluster будет развернут при помощи microk8s. В качестве балансировщика нагрузки и по совместительству web-сервера будет выступать nginx, а точнее nginx-ingress-controller, который есть в microk8s.


Рассмотрим развертывания каждого компонента по отдельности.

Шаг 1: База данных

Для базы данных используем следующий yaml

apiVersion: v1 kind: Service metadata:   name: db spec:   ports:     - port: 5432   selector:     app: db   clusterIP: None --- apiVersion: apps/v1 kind: Deployment metadata:   name: db spec:   selector:     matchLabels:       app: db   strategy:     type: Recreate   template:     metadata:       labels:         app: db     spec:       containers:         - image: postgres:9.6           name: db           env:             - name: POSTGRES_USER               value: admin              - name: POSTGRES_PASSWORD               value: admin              - name: POSTGRES_DB               value: dbname            ports:             - containerPort: 5432               name: db 

В файле сразу описан и сервис, и развертывание базы. Как образ ,использован образ Postgres 9.6

Для создания развертывания исполним командуkubectl apply -f db.yaml

Шаг 2: Grafana

Для Grafana используем следующий yaml

apiVersion: v1 kind: Service metadata:   name: grafana spec:   ports:     - port: 3000   selector:     app: grafana   clusterIP: None ---  apiVersion: apps/v1 kind: Deployment metadata:   name: grafana spec:   selector:     matchLabels:       app: grafana   strategy:     type: Recreate   template:     metadata:       labels:         app: grafana     spec:       containers:         - image: grafana/grafana:master           name: grafana             ports:             - containerPort: 3000               name: grafana

Развертывание похоже на то, что использовано для базы данных. Разница в образе (grafana/grafana:master) и в выставляемом порте.

Аналогично выполним командуkubectl apply -f grafana.yaml

Шаг 3: Loki

Как и выше yaml

apiVersion: v1 kind: Service metadata:   name: loki spec:   ports:     - port: 3100   selector:     app: loki   clusterIP: None ---  apiVersion: apps/v1 kind: Deployment metadata:   name: loki spec:   selector:     matchLabels:       app: loki   strategy:     type: Recreate   template:     metadata:       labels:         app: loki     spec:       containers:         - image: grafana/loki:latest           name: loki             ports:             - containerPort: 3100               name: loki 

И командаkubectl apply -f grafana.yaml

Шаг 4: Promtail

Для promtail понадобится Helm. Можно использовать helm, встроенный в microk8s(поддерживаются версии 2 и 3). Также можно установить Helm отдельно. В таком случае необходимо в файле config, расположенном в директории .kube, указать ip кластера. Можно выполнить microk8s config

Шаг 5: Ingress

Для nginx используем следующий файл.

apiVersion: networking.k8s.io/v1 kind: Ingress metadata:   name: server spec:   rules:      #for nginxinc controller host should be set     - http:         paths:           - path: /             pathType: Prefix             backend:               service:                 name: server                 port:                   number: 8024                              - path: /grafana             pathType: Prefix             backend:               service:                 name: grafana                 port:                   number: 3000        

И команду kubectl apply -f ingress.yaml

Шаг 7: Приложение

Этот шаг не похож ни на один предыдущий. Здесь не будет использовано ни одного yaml и ни одного готового Docker образа. Нужное нам развертывание будет создано сразу после процесса сборки. Для этого используется Maven + jkube maven plugin

Сначала install собирает jar с приложением, затем k8s:resource генерирует ресурсы, потом k8s:build создаст Docker oбраз и k8s:deploy сделает развертывание.

Ниже пример конфигурации плагина для данного процесса

<profile>             <id>kube</id>             <properties>                 <spring.profiles.active>docker</spring.profiles.active>             </properties>             <build>                 <plugins>                     <plugin>                         <groupId>org.eclipse.jkube</groupId>                         <artifactId>kubernetes-maven-plugin</artifactId>                         <version>1.1.1</version>                         <configuration>                             <verbose>true</verbose>                                        <images>                                 <image>                                     <name>imagename:latest</name>                                     <alias>some-alias/alias>                                     <build>                                         <maintainer>John Smith</maintainer>                                         <from>fabric8/java-centos-openjdk11-jre</from>                                         <assembly>                                             <inline>                                                 <baseDirectory>/deployments</baseDirectory>                                             </inline>                                          </assembly>                                     </build>                                 </image>                             </images>                          </configuration>                         <executions>                             <execution>                                 <id>run</id>                                 <goals>                                     <goal>resource</goal>                                     <goal>build</goal>                                     <goal>deploy</goal>                                 </goals>                             </execution>                         </executions>                     </plugin>                 </plugins>             </build>          </profile>

Образ описан под тегом image. Также можно использовать один из генераторов.

Также необходимо создать сервис. Для этого выполним

kubectl expose deployment server --type=LoadBalancer --name=server --port=<some-port>

Почему был использован данный способ создания сервиса, ведь сервис можно сконфигурировать также в плагине? На данный момент, была обнаружена ошибка в момент старта приложения в поде : вместо ip сервиса, приходит строка tcp://<ip-service>. Это приводит к NumberFormatException.

Шаг 8: Проверка доступа

В браузере или с помощью curl проверить, что localhost возвращает страницу приложения, localhost/grafana покажет страницу входа в Grafana.

Шаг 9: Отобразить логи

Для этого необходимо войти в Grafana с помощью логина/пароля admin . После необходимо указать ,в качестве источника данных Loki(http://loki:3000). Затем в explore ввести {app=»название-приложения»} .

P.S.

Сбор логов был основан на данной статье.

ссылка на оригинал статьи https://habr.com/ru/post/550554/


Комментарии

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

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