С помощью этого руководства вы научитесь запускать и разворачивать приложения в управляемом кластере Managed Kubernetes на платформе Cloud.ru Evolution, используя YAML-манифесты и Helm-чарты. Также вы научитесь использовать Artifact Registry для загрузки образов с Helm-чартами и запуска приложений из них.
Helm — менеджер пакетов для Kubernetes, который упрощает установку, развертывание и управление приложениями. Он позволяет упаковывать сложные приложения в виде «чартов», которые представляют пакеты с необходимыми для работы ресурсами.
Helm Chart — пакет, который описывает набор ресурсов Kubernetes, необходимых для установки, обновления и управления приложением или службой.
Вы будете использовать следующие сервисы:
«Виртуальные машины» — сервис, в рамках которого предоставляется виртуальная машина.
Managed Kubernetes — сервис управления кластерами Kubernetes на вычислительных ресурсах облака.
Artifact Registry для хранения, совместного использования и управления Docker-образами, Deb-пакетами, RPM-пакетами, Helm-чартами и файлами любого типа (generic).
Docker — система контейнеризации.
Helm — пакетный менеджер для Kubernetes.
kubectl — инструмент командной строки, позволяющий запускать команды для кластеров Kubernetes.
Шаги:
Если вы уже зарегистрированы, войдите под своей учетной записью.
Убедитесь, что у вас достаточно прав для создания реестра и загрузки артефактов в сервисе Artifact Registry.
Создайте группу безопасности с правилами (или создайте правило в рамках существующей группы безопасности) по TCP порту 22 для внешнего IP-адреса локальной машины. Узнайте адрес локальной машины через сервис https://www.myip.ru.
Создайте бесплатную виртуальную машину с параметрами:
Название — vm-helm.
Образ — на вкладке Публичные выберите Ubuntu 22.04.
Публичный IP — оставьте Арендовать новый или выберите IP-адрес из списка арендованных.
Логин — оставьте значение по умолчанию или укажите новый.
Метод аутентификации — Пароль и Публичный ключ.
Пароль — задайте пароль пользователя.
Группы безопасности — укажите группу, созданную перед началом работы.
Остальные параметры оставьте по умолчанию или выберите на свое усмотрение.
В списке виртуальных машин появится новая ВМ. Примерно через минуту ее статус должен измениться на «Запущена».
Установите Docker на ВМ:
sudo apt update -ysudo apt upgrade -ycurl -fsSL get.docker.com -o get-docker.sh && sh get-docker.shsudo groupadd dockersudo usermod -aG docker $USERnewgrp docker
Чтобы проверить, что Docker установлен и работает корректно, выполните команду:
docker version
Создайте кластер Managed Kubernetes с хотя бы одной группой узлов.
При создании группы узлов укажите следующие параметры:
Гарантированная доля vCPU, % — 30.
CPU, шт — 2.
RAM, ГБ — 4.
Объем хранилища, ГБ — 30.
Количество узлов — 1.
Создание кластера занимает примерно пять минут.
Выполните подключение к кластеру Managed Kubernetes с ВМ:
Установите на ВМ kubectl и cloudlogin.
Проверьте подключение:
kubectl get nodes
Если отобразится список узлов, подключение настроено.
Воспользуйтесь скриптом установки Helm из официального источника:
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3chmod 700 get_helm.sh./get_helm.sh
Проверьте корректность установки Helm с помощью команды:
helm version
В ответ на эту команду вы увидите информацию о версии сборки Helm.
Убедитесь, что на виртуальной машине установлен Python, выполнив в консоли команду:
python3 --version
Установите менеджер пакетов Python pip3:
sudo apt updatesudo apt install python3-pip
Чтобы проверить установку, выполните команду:
pip3 --version
Установите Flask — приложение для создания веб-приложений на Python:
sudo pip3 install flask
Чтобы проверить установку, выполните команду:
flask --version
В домашней директории виртуальной машины создайте каталог my-lab, а в нем — my-app и перейдите в него:
mkdir ~/my-labmkdir ~/my-lab/my-appcd ~/my-lab/my-app
В каталоге my-app создайте файл app.py:
nano app.py
В файл app.py добавьте код:
import osfrom flask import Flaskapp = Flask(__name__)@app.route('/')def get_app_message():message = os.getenv('APP_MESSAGE', 'Переменная не найдена')return messageif __name__ == '__main__':app.run(host='0.0.0.0', port=5000)
Это код простого веб-приложения, которое возвращает значение переменной окружения APP_MESSAGE.
В каталоге my-app создайте файл requirements.txt со следующим содержимым:
Flask==2.3.3
В каталоге my-app создайте файл Dockerfile:
nano Dockerfile
В файл Dockerfile добавьте:
FROM python:3.9WORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txtCOPY . .CMD ["python", "app.py"]
В каталоге my-app соберите докер-образ приложения:
docker build -t my-app:1.0 .
Проверьте работоспособность приложения, запустив докер-контейнер:
docker run -d -p 5000:5000 -e APP_MESSAGE="Hello World" my-app:1.0
Введите команду:
curl http://localhost:5000 && echo
В результате вы увидите строку с Hello World — это результат работы нашего приложения.
Чтобы перетегировать ранее собранные образы и залить их в реестр, выполните команды:
docker tag my-app:1.0 <yourproject_registry>.cr.cloud.ru/my-app:1.0docker push <yourproject_registry>.cr.cloud.ru/my-app:1.0
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
В результате образ my-app:1.0 появится в Artifact Registry.
Перейдите в каталог my-lab:
cd ~/my-lab
Создайте файл myapp-configmap.yaml:
nano myapp-configmap.yaml
В файл myapp-configmap.yaml скопируйте код манифеста:
apiVersion: v1kind: ConfigMapmetadata:name: env-app-configdata:APP_MESSAGE: "Hello from Kubernetes!"
Создайте файл myapp-deployment.yaml:
nano myapp-deployment.yaml
В файл myapp-deployment.yaml скопируйте код манифеста:
apiVersion: apps/v1kind: Deploymentmetadata:name: env-appspec:replicas: 2selector:matchLabels:app: env-apptemplate:metadata:labels:app: env-appspec:containers:- name: appimage: <yourproject_registry>.cr.cloud.ru/my-app:1.0ports:- containerPort: 5000env:- name: APP_MESSAGEvalueFrom:configMapKeyRef:name: env-app-configkey: APP_MESSAGE
Где <yourproject_registry> — название вашего реестра.
Создайте файл myapp-service.yaml:
nano myapp-service.yaml
В файл myapp-service.yaml скопируйте код манифеста:
apiVersion: v1kind: Servicemetadata:name: env-app-servicespec:type: LoadBalancerselector:app: env-appports:- port: 80targetPort: 5000
Создайте объекты Kubernetes на основе созданных YAML-манифестов:
kubectl apply -f myapp-configmap.yamlkubectl apply -f myapp-deployment.yamlkubectl apply -f myapp-service.yaml
Убедитесь, что поды развернуты и находятся в статусе «Running»:
kubectl get pods
Убедитесь, что в поле EXTERNAL-IP сервиса myapp-service назначен публичный IP-адрес:
kubectl get svc env-app-service
Назначение публичного адреса занимает около пяти минут.
Чтобы проверить работоспособность приложения и доступ к нему извне, в командной строке выполните:
curl http://<EXTERNAL_IP> && echo
Отобразится значение переменной APP_MESSAGE, указанное в файле configmap.yaml:
"Hello from Kubernetes!"
Таким образом вы убедились в работоспособности приложения, которое возвращает значения переменной из ConfigMap.
Удалите созданные сущности Kubernetes:
kubectl delete svc env-app-servicekubectl delete configmap env-app-configkubectl delete deployment env-app
В каталоге my-lab создайте базовую структуру Helm-чарта:
helm create myapp-chart
Перейдите в каталог myapp-chart и из каталога templates удалите лишние файлы:
В каталоге myapp-chart создайте файл values.yaml:
nano values.yaml
В values.yaml добавьте содержимое:
# Название приложения и параметрыappName: env-appreplicaCount: 2# Настройки образаimage:repository: <yourproject_registry>.cr.cloud.ru/my-apptag: "1.0"pullPolicy: IfNotPresent# Настройки сервисаservice:name: env-app-servicetype: LoadBalancerport: 80targetPort: 5000# Настройки ConfigMapconfigmap:name: env-app-configappMessage: "Hello from Helm!"# Метки приложенияlabels:app: env-app
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
Создайте файл templates/configmap.yaml:
nano templates/configmap.yaml
В configmap.yaml добавьте следующее содержимое:
apiVersion: v1kind: ConfigMapmetadata:name: {{ .Values.configmap.name }}labels:app: {{ .Values.labels.app }}data:APP_MESSAGE: {{ .Values.configmap.appMessage | quote }}
Создайте файл templates/deployment.yaml:
nano templates/deployment.yaml
В deployment.yaml добавьте следующее содержимое:
apiVersion: apps/v1kind: Deploymentmetadata:name: {{ .Values.appName }}labels:app: {{ .Values.labels.app }}spec:replicas: {{ .Values.replicaCount }}selector:matchLabels:app: {{ .Values.labels.app }}template:metadata:labels:app: {{ .Values.labels.app }}annotations:helm-revision: {{ .Release.Revision | quote }}spec:containers:- name: {{ .Values.appName }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"imagePullPolicy: {{ .Values.image.pullPolicy }}ports:- containerPort: {{ .Values.service.targetPort }}env:- name: APP_MESSAGEvalueFrom:configMapKeyRef:name: {{ .Values.configmap.name }}key: APP_MESSAGE
Создайте файл templates/service.yaml:
nano templates/service.yaml
В service.yaml добавьте следующее содержимое:
apiVersion: v1kind: Servicemetadata:name: {{ .Values.service.name }}labels:app: {{ .Values.labels.app }}spec:type: {{ .Values.service.type }}selector:app: {{ .Values.labels.app }}ports:- port: {{ .Values.service.port }}targetPort: {{ .Values.service.targetPort }}
Проверьте синтаксис чарта:
helm lint .
Перейдите в каталог myapp-chart и разверните приложение:
cd ~/my-lab/myapp-charthelm install myapp .
Проверьте, что поды запущены и находятся в статусе «Running»:
kubectl get pods
Убедитесь, что для сервиса env-app-service назначен внешний IP-адрес EXTERNAL-IP:
kubectl get svc env-app-service
Назначение внешнего IP-адреса занимает около пяти минут.
Проверьте вывод значения переменной APP_MESSAGE:
curl http://<EXTERNAL_IP> && echo
В консольной строке вы увидите значение:
Hello from Helm!
Внесите изменения в файл values.yaml, изменив поле appMessage в разделе configmap и количество реплик:
# Название приложения и параметрыappName: env-appreplicaCount: 4# Настройки образаimage:repository: <yourproject_registry>.cr.cloud.ru/my-apptag: "1.0"pullPolicy: IfNotPresent# Настройки сервисаservice:name: env-app-servicetype: LoadBalancerport: 80targetPort: 5000# Настройки ConfigMapconfigmap:name: env-app-configappMessage: "Hello from Helm! - Updated version"# Метки приложенияlabels:app: env-app
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
Обновите Helm-чарт и проверьте значение переменной окружения в выводе APP_MESSAGE:
helm upgrade myapp .curl http://<EXTERNAL_IP> && echo
Теперь в консольной строке вы увидите значение:
Hello from Helm! - Updated version
Проверьте, что в статусе «Running» теперь четыре пода:
kubectl get pods
При обновлении Helm-чарта были автоматически отмасштабированы и перезапущены поды приложения. Теперь они выводят обновленное значение переменной окружения APP_MESSAGE.
В values.yaml измените тег на несуществующий:
# Название приложения и параметрыappName: env-appreplicaCount: 4# Настройки образаimage:repository: <yourproject_registry>.cr.cloud.ru/my-apptag: "broken image"pullPolicy: IfNotPresent# Настройки сервисаservice:name: env-app-servicetype: LoadBalancerport: 80targetPort: 5000# Настройки ConfigMapconfigmap:name: env-app-configappMessage: "Hello from Helm! - Updated version"# Метки приложенияlabels:app: env-app
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
Обновите helm-чарт:
helm upgrade myapp .
Новые поды не смогут скачать образ.
Убедитесь, что поды находятся в статусе «ImagePullBackOff» или «ErrImagePull»:
kubectl get pods
Откатите приложение на предыдущую версию и проверьте статус подов.
helm rollback myappkubectl get pods
Они должны быть в статусе «Running».
Проверьте вывод значения переменной APP_MESSAGE:
curl http://<EXTERNAL_IP> && echo
Приложение выводит значение переменной:
Hello from Helm! - Updated version
Откат приложения прошел успешно.
Удалите приложение, запущенное через Helm-chart:
helm uninstall myapp
Внесите изменения в файл values.yaml:
# Название приложения и параметрыappName: env-appreplicaCount: 4# Настройки образаimage:repository: <yourproject_registry>.cr.cloud.ru/my-apptag: "1.0"pullPolicy: IfNotPresent# Настройки сервисаservice:name: env-app-servicetype: LoadBalancerport: 80targetPort: 5000# Настройки ConfigMapconfigmap:name: env-app-configappMessage: "This Application is installed from the Artifact Registry helm-chart image"# Метки приложенияlabels:app: env-app
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
Упакуйте Helm-чарт в архив .tgz:
cd ~/my-labhelm package myapp-chart/. --version 1.0.0
Загрузите упакованный чарт в OCI-реестр:
helm push myapp-chart-1.0.0.tgz oci://<yourproject_registry>.cr.cloud.ru
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
Запустите Helm-чарт приложения из OCI-реестра Artifact Registry:
helm install myapp-helm-registry oci://<yourproject_registry>.cr.cloud.ru/myapp-chart --version 1.0.0
Где <yourproject_registry> — название вашего реестра в Artifact Registry.
Убедитесь, что поды находятся в статусе «Running» и дождитесь получения External-IP:
kubectl get podskubectl get svc env-app-service
Назначение публичного адреса занимает около пяти минут.
Проверьте вывод значения переменной APP_MESSAGE:
curl http://<EXTERNAL_IP> && echo
Вы научились:
работать с YAML-манифестами в Kubernetes;
запускать и откатывать версии приложения с помощью Helm-чартов;
загружать и скачивать образы Helm-чартов из Artifact Registry.