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

Запуск весенних загрузочных приложений с Minikube

1. обзор

В этомprevious article мы рассмотрели теоретическое введение в Kubernetes.

В этом руководствеwe’ll discuss how to deploy a Spring Boot application on a local Kubernetes environment, also known as Minikube.

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

  • Установите Minikube на наш локальный компьютер

  • Разработать пример приложения, состоящего из двух сервисов Spring Boot

  • Настройте приложение в кластере с одним узлом, используя Minikube

  • Разверните приложение, используя конфигурационные файлы

2. Установка Minikube

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

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

После завершения установки мы можем запустить 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, которое необходимо для вызова ресурсов извне кластера, т.е. g. из нашего браузера.

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

$> minikube dashboard

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

4. Демо-приложение

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

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

Бэкэнд предоставляет одну конечную точку REST на порту 8080, возвращаяString, содержащее ее имя хоста. Интерфейс доступен через порт 8081, он просто вызывает внутреннюю конечную точку и возвращает свой ответ.

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

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

We have to make sure here that we trigger the build process on the Docker host of the Minikube cluster, иначе 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. Простое развертывание с использованием императивных команд

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

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

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

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

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

С помощью–port мы указываем, что развертывание открывает порт 8080 для своих модулей (поскольку наше приложениеdemo-backend прослушивает порт 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

Если мы хотим просмотреть журналы приложений, нам сначала понадобится Pod ID:

$> kubectl get pods
$> kubectl logs 

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

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

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

–type=NodePort делает Сервис доступным извне кластера. Он будет доступен в<NodeIP>:<NodePort>, т.е. e. служба отображает любой запрос, поступающий в<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           8080:30117/TCP   11m

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

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

5.4. Вызов службы

Теперь мы можем впервые позвонить в наш бэкэнд-сервис:

$> minikube service demo-backend

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

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

После этого мы можем удалить Сервис и Развертывание:

$> 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.

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

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 определяет, как развертывание находит, какими модулями нужно управлять. В этом случае мы просто выбираем одну метку, определенную в шаблоне Pod (app: demo-backend).

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

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

  • Модули обозначены какapp: demo-backend.

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

  • Стручки открывают порт 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           8080/TCP         30s

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

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

После этого мы можем определить 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

И фронтенд, и бэкэнд почти идентичны,the only difference between backend and frontend is the spec of the Service:

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

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

6.5. Развертывание приложения Frontend

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

$> 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. Очистка служб и развертываний

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

$> 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, а также файлы конфигурации

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