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 .