Перейти к основному содержимому

Запуск приложений Spring Boot с Minikube

· 8 мин. чтения

1. Обзор

В этой предыдущей статье мы рассмотрели теоретическое введение в Kubernetes.

В этом руководстве мы обсудим, как развернуть приложение Spring Boot в локальной среде Kubernetes, также известной как Minikube.

В рамках этой статьи мы:

  • Установите Minikube на нашу локальную машину
  • Разработайте пример приложения, состоящего из двух сервисов Spring Boot.
  • Настройте приложение в кластере с одним узлом с помощью Minikube.
  • Разверните приложение с помощью конфигурационных файлов

2. Установка миникуба

Установка Minikube в основном состоит из трех шагов: установка гипервизора (например, VirtualBox), CLI kubectl , а также самого Minikube.

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

После завершения установки мы можем запустить Minikube, установить VirtualBox в качестве гипервизора и настроить kubectl для взаимодействия с кластером под названием minikube :

$> minikube start
$> minikube config set vm-driver virtualbox
$> kubectl config use-context minikube

После этого мы можем убедиться, что kubectl правильно взаимодействует с нашим кластером:

$> kubectl cluster-info

Вывод должен выглядеть так:

Kubernetes master is running at https://192.168.99.100:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

На этом этапе мы будем держать IP-адрес в ответе близким ( 192.168.99.100 в нашем случае). Позже мы будем называть его NodeIP , который необходим для вызова ресурсов из-за пределов кластера, например, из нашего браузера.

Наконец, мы можем проверить состояние нашего кластера:

$> minikube dashboard

Эта команда открывает сайт в нашем браузере по умолчанию, который предоставляет обширный обзор состояния нашего кластера.

4. Демонстрационное приложение

Поскольку наш кластер запущен и готов к развертыванию, нам нужно демонстрационное приложение.

Для этой цели мы создадим простое приложение «Hello world», состоящее из двух сервисов Spring Boot, которые мы назовем frontend и backend .

Серверная часть предоставляет одну конечную точку REST на порту 8080, возвращая строку , содержащую ее имя хоста. Внешний интерфейс доступен на порту 8081, он просто вызовет внутреннюю конечную точку и вернет свой ответ.

После этого нам нужно создать образ Docker для каждого приложения. Все необходимые для этого файлы также доступны на GitHub .

Подробные инструкции по сборке образов Docker см. в Dockerizing a Spring Boot Application .

Здесь мы должны убедиться, что запускаем процесс сборки на хосте Docker кластера Minikube , иначе Minikube не найдет образы позже во время развертывания. Кроме того, рабочая область на нашем хосте должна быть смонтирована в виртуальной машине Minikube:

$> minikube ssh
$> cd /c/workspace/tutorials/spring-cloud/spring-cloud-kubernetes/demo-backend
$> docker build --file=Dockerfile \
--tag=demo-backend:latest --rm=true .

После этого мы можем выйти из виртуальной машины Minikube, все дальнейшие шаги будут выполняться на нашем хосте с помощью инструментов командной строки kubectl и minikube .

5. Простое развертывание с помощью императивных команд

На первом этапе мы создадим развертывание для нашего демо- приложения, состоящего только из одного пода. Исходя из этого, мы обсудим некоторые команды, чтобы мы могли проверить развертывание, просмотреть журналы и очистить его в конце.

5.1. Создание развертывания

Мы будем использовать kubectl , передав все необходимые команды в качестве аргументов:

$> kubectl run demo-backend --image=demo-backend:latest \
--port=8080 --image-pull-policy Never

Как мы видим, мы создаем Deployment под названием demo-backend, экземпляр которого создается из образа, также называемого demo-backend , с последней версией .

С помощью –port мы указываем, что развертывание открывает порт 8080 для своих подов (поскольку наше демонстрационное серверное приложение прослушивает порт 8080).

Флаг –image-pull-policy Never гарантирует, что Minikube не будет пытаться извлечь образ из реестра, а вместо этого возьмет его с локального хоста Docker.

5.2. Проверка развертывания

Теперь мы можем проверить, было ли развертывание успешным:

$> kubectl get deployments

Вывод выглядит следующим образом:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend 1 1 1 1 19s

Если мы хотим просмотреть журналы приложений, нам сначала нужен идентификатор пода:

$> kubectl get pods
$> kubectl logs <pod id>

5.3. Создание службы для развертывания

Чтобы сделать конечную точку REST нашего серверного приложения доступной, нам нужно создать службу:

$> kubectl expose deployment demo-backend --type=NodePort

–type=NodePort делает Сервис доступным из-за пределов кластера. Он будет доступен в <NodeIP>:<NodePort> , т. е. служба сопоставляет любой запрос, входящий в <NodePort> , с портом 8080 назначенных ему подов.

Мы используем команду expose, поэтому NodePort будет установлен кластером автоматически (это техническое ограничение), диапазон по умолчанию — 30000-32767. Чтобы получить порт по нашему выбору, мы можем использовать файл конфигурации, как мы увидим в следующем разделе.

Мы можем убедиться, что сервис был успешно создан:

$> kubectl get services

Вывод выглядит следующим образом:

NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend NodePort 10.106.11.133 <none> 8080:30117/TCP 11m

Как мы видим, у нас есть один Service под названием demo-backend типа NodePort , который доступен по внутреннему IP-адресу кластера 10.106.11.133.

Мы должны внимательно посмотреть на столбец PORT(S): поскольку порт 8080 был определен в развертывании, служба перенаправляет трафик на этот порт. Однако, если мы хотим вызвать демо-бэкенд из нашего браузера, мы должны использовать порт 30117, доступный снаружи кластера.

5.4. Звонок в службу

Теперь мы можем вызвать наш серверный сервис в первый раз:

$> minikube service demo-backend

Эта команда запустит наш браузер по умолчанию, открыв <NodeIP>:<NodePort>. В нашем примере это будет http://192.168.99.100:30117 .

5.5. Очистка службы и развертывания

После этого мы можем удалить Service и Deployment:

$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

6. Комплексное развертывание с использованием файлов конфигурации

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

Файлы конфигурации — отличный способ документирования нашего развертывания, и они могут управляться версиями.

6.1. Определение службы для нашего серверного приложения

Давайте переопределим наш сервис для бэкенда с помощью файла конфигурации:

kind: Service
apiVersion: v1
metadata:
name: demo-backend
spec:
selector:
app: demo-backend
ports:
- protocol: TCP
port: 8080
type: ClusterIP

Мы создаем Service с именем demo-backend , обозначенным полем metadata: name .

Он нацелен на TCP-порт 8080 на любом поде с меткой app=demo-backend .

Наконец, введите: ClusterIP указывает, что он доступен только внутри кластера (поскольку на этот раз мы хотим вызывать конечную точку из нашего демонстрационного внешнего приложения, а не напрямую из браузера, как в предыдущем примере).

6.2. Определение развертывания для серверного приложения

Далее мы можем определить фактическое развертывание:

apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-backend
spec:
selector:
matchLabels:
app: demo-backend
replicas: 3
template:
metadata:
labels:
app: demo-backend
spec:
containers:
- name: demo-backend
image: demo-backend:latest
imagePullPolicy: Never
ports:
- containerPort: 8080

Мы создаем Deployment с именем demo-backend , обозначенным полем metadata: name .

Поле spec: selector определяет, как Deployment находит, какими модулями управлять. В этом случае мы просто выбираем одну метку, определенную в шаблоне пода ( app: demo-backend ).

Мы хотим иметь три реплицированных пода, которые мы указываем полем replicas .

Поле шаблона определяет фактический под:

  • Поды помечены как приложение: demo-backend.
  • Поле template: spec указывает, что каждая репликация Pod запускает один контейнер demo-backend с последней версией.
  • Pods открывают порт 8080

6.3. Развертывание серверного приложения

Теперь мы можем инициировать развертывание:

$> kubectl create -f backend-deployment.yaml

Давайте проверим, что развертывание прошло успешно:

$> kubectl get deployments

Вывод выглядит следующим образом:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend 3 3 3 3 25s

Мы также можем проверить, доступен ли Сервис:

$> kubectl get services

Вывод выглядит следующим образом:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend ClusterIP 10.102.17.114 <none> 8080/TCP 30s

Как мы видим, Service имеет тип ClusterIP и не предоставляет внешний порт в диапазоне 30000-32767, в отличие от нашего предыдущего примера в разделе 5.

6.4. Развертывание и определение службы для нашего внешнего приложения

После этого мы можем определить Service и Deployment для интерфейса:

kind: Service
apiVersion: v1
metadata:
name: demo-frontend
spec:
selector:
app: demo-frontend
ports:
- protocol: TCP
port: 8081
nodePort: 30001
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-frontend
spec:
selector:
matchLabels:
app: demo-frontend
replicas: 3
template:
metadata:
labels:
app: demo-frontend
spec:
containers:
- name: demo-frontend
image: demo-frontend:latest
imagePullPolicy: Never
ports:
- containerPort: 8081

И интерфейс, и сервер почти идентичны, единственная разница между сервером и интерфейсом — это `` спецификация Сервиса :

Для внешнего интерфейса мы определяем тип как NodePort (поскольку мы хотим сделать внешний интерфейс доступным за пределами кластера). Серверная часть должна быть доступна только внутри кластера, поэтому тип был ClusterIP .

Как было сказано ранее, мы также указываем NodePort вручную, используя поле nodePort .

6.5. Развертывание внешнего интерфейса

Теперь мы можем инициировать это развертывание таким же образом:

$> kubectl create -f frontend-deployment.yaml

Давайте быстро проверим, что развертывание прошло успешно и Сервис доступен:

$> kubectl get deployments
$> kubectl get services

После этого мы, наконец, можем вызвать конечную точку REST внешнего приложения:

$> minikube service demo-frontend

Эта команда снова запустит наш браузер по умолчанию, открыв <NodeIP>:<NodePort> , в данном примере это http://192.168.99.100:30001 .

6.6. Очистка служб и развертываний

В конце концов, мы можем очиститься, удалив Services и Deployments:

$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

7. Заключение

В этой статье мы кратко рассмотрели, как развернуть приложение Spring Boot «Hello world» в локальном кластере Kubernetes с помощью Minikube.

Мы подробно обсудили, как:

  • Установите Minikube на нашу локальную машину
  • Разработайте и соберите пример, состоящий из двух приложений Spring Boot.
  • Разверните службы в кластере с одним узлом, используя императивные команды с kubectl , а также файлы конфигурации .

Как всегда, полный исходный код примеров доступен на GitHub .