Тема развертывания 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: v1kind: Servicemetadata: name: dbspec: ports: - port: 5432 selector: app: db clusterIP: None---apiVersion: apps/v1kind: Deploymentmetadata: name: dbspec: 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: v1kind: Servicemetadata: name: grafanaspec: ports: - port: 3000 selector: app: grafana clusterIP: None---apiVersion: apps/v1kind: Deploymentmetadata: name: grafanaspec: 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: v1kind: Servicemetadata: name: lokispec: ports: - port: 3100 selector: app: loki clusterIP: None---apiVersion: apps/v1kind: Deploymentmetadata: name: lokispec: 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/v1kind: Ingressmetadata: name: serverspec: 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://personeltest.ru/away/loki:3000). Затем в explore ввести {app="название-приложения"} .
PS.
Сбор логов был основан на данной статье