Облачная платформаEvolution

Запуск приложения с помощью YAML-манифестов и Helm-чартов в Managed Kubernetes

Эта статья полезна?

С помощью этого руководства вы научитесь запускать и разворачивать приложения в управляемом кластере 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.

Шаги:

Перед началом работы

  1. Если вы уже зарегистрированы, войдите под своей учетной записью.

  2. Убедитесь, что у вас достаточно прав для создания реестра и загрузки артефактов в сервисе Artifact Registry.

  3. Создайте группу безопасности с правилами (или создайте правило в рамках существующей группы безопасности) по TCP порту 22 для внешнего IP-адреса локальной машины. Узнайте адрес локальной машины через сервис https://www.myip.ru.

1. Сгенерируйте ключевую пару и загрузите публичный ключ SSH в облако Cloud.ru Evolution

2. Создайте виртуальную машину и установите Docker

    • Названиеvm-helm.

    • Образ — на вкладке Публичные выберите Ubuntu 22.04.

    • Публичный IP — оставьте Арендовать новый или выберите IP-адрес из списка арендованных.

    • Логин — оставьте значение по умолчанию или укажите новый.

    • Метод аутентификацииПароль и Публичный ключ.

    • Пароль — задайте пароль пользователя.

    • Группы безопасности — укажите группу, созданную перед началом работы.

    Остальные параметры оставьте по умолчанию или выберите на свое усмотрение.

    В списке виртуальных машин появится новая ВМ. Примерно через минуту ее статус должен измениться на «Запущена».

  1. Установите Docker на ВМ:

    sudo apt update -y
    sudo apt upgrade -y
    curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
    sudo groupadd docker
    sudo usermod -aG docker $USER
    newgrp docker
  2. Чтобы проверить, что Docker установлен и работает корректно, выполните команду:

    docker version

3. Создайте кластер Managed Kubernetes

  1. Создайте кластер Managed Kubernetes с хотя бы одной группой узлов.

    При создании группы узлов укажите следующие параметры:

    • Гарантированная доля vCPU, %30.

    • CPU, шт2.

    • RAM, ГБ4.

    • Объем хранилища, ГБ30.

    • Количество узлов1.

    Создание кластера занимает примерно пять минут.

  2. Выполните подключение к кластеру Managed Kubernetes с ВМ:

    1. Установите на ВМ kubectl и cloudlogin.

    2. Проверьте подключение:

    kubectl get nodes

    Если отобразится список узлов, подключение настроено.

4. Установите Helm CLI

  1. Воспользуйтесь скриптом установки Helm из официального источника:

    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
  2. Проверьте корректность установки Helm с помощью команды:

    helm version

    В ответ на эту команду вы увидите информацию о версии сборки Helm.

5. Установите Flask на виртуальную машину

  1. Убедитесь, что на виртуальной машине установлен Python, выполнив в консоли команду:

    python3 --version
  2. Установите менеджер пакетов Python pip3:

    sudo apt update
    sudo apt install python3-pip
  3. Чтобы проверить установку, выполните команду:

    pip3 --version
  4. Установите Flask — приложение для создания веб-приложений на Python:

    sudo pip3 install flask
  5. Чтобы проверить установку, выполните команду:

    flask --version

6. Создайте докер-образ приложения на базе Flask

  1. В домашней директории виртуальной машины создайте каталог my-lab, а в нем — my-app и перейдите в него:

    mkdir ~/my-lab
    mkdir ~/my-lab/my-app
    cd ~/my-lab/my-app
  2. В каталоге my-app создайте файл app.py:

    nano app.py
  3. В файл app.py добавьте код:

    import os
    from flask import Flask
    app = Flask(__name__)
    @app.route('/')
    def get_app_message():
    message = os.getenv('APP_MESSAGE', 'Переменная не найдена')
    return message
    if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

    Это код простого веб-приложения, которое возвращает значение переменной окружения APP_MESSAGE.

  4. В каталоге my-app создайте файл requirements.txt со следующим содержимым:

    Flask==2.3.3
  5. В каталоге my-app создайте файл Dockerfile:

    nano Dockerfile
  6. В файл Dockerfile добавьте:

    FROM python:3.9
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    CMD ["python", "app.py"]
  7. В каталоге my-app соберите докер-образ приложения:

    docker build -t my-app:1.0 .
  8. Проверьте работоспособность приложения, запустив докер-контейнер:

    docker run -d -p 5000:5000 -e APP_MESSAGE="Hello World" my-app:1.0
  9. Введите команду:

    curl http://localhost:5000 && echo

    В результате вы увидите строку с Hello World — это результат работы нашего приложения.

7. Создайте приватный реестр в Artifact Registry и загрузите образ приложения

  1. Чтобы перетегировать ранее собранные образы и залить их в реестр, выполните команды:

    docker tag my-app:1.0 <yourproject_registry>.cr.cloud.ru/my-app:1.0
    docker push <yourproject_registry>.cr.cloud.ru/my-app:1.0

    Где <yourproject_registry> — название вашего реестра в Artifact Registry.

    В результате образ my-app:1.0 появится в Artifact Registry.

8. Разверните приложение в кластере Managed Kubernetes с помощью YAML-манифестов

  1. Перейдите в каталог my-lab:

    cd ~/my-lab
  2. Создайте файл myapp-configmap.yaml:

    nano myapp-configmap.yaml
  3. В файл myapp-configmap.yaml скопируйте код манифеста:

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: env-app-config
    data:
    APP_MESSAGE: "Hello from Kubernetes!"
  4. Создайте файл myapp-deployment.yaml:

    nano myapp-deployment.yaml
  5. В файл myapp-deployment.yaml скопируйте код манифеста:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: env-app
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: env-app
    template:
    metadata:
    labels:
    app: env-app
    spec:
    containers:
    - name: app
    image: <yourproject_registry>.cr.cloud.ru/my-app:1.0
    ports:
    - containerPort: 5000
    env:
    - name: APP_MESSAGE
    valueFrom:
    configMapKeyRef:
    name: env-app-config
    key: APP_MESSAGE

    Где <yourproject_registry> — название вашего реестра.

  6. Создайте файл myapp-service.yaml:

    nano myapp-service.yaml
  7. В файл myapp-service.yaml скопируйте код манифеста:

    apiVersion: v1
    kind: Service
    metadata:
    name: env-app-service
    spec:
    type: LoadBalancer
    selector:
    app: env-app
    ports:
    - port: 80
    targetPort: 5000
  8. Создайте объекты Kubernetes на основе созданных YAML-манифестов:

    kubectl apply -f myapp-configmap.yaml
    kubectl apply -f myapp-deployment.yaml
    kubectl apply -f myapp-service.yaml
  9. Убедитесь, что поды развернуты и находятся в статусе «Running»:

    kubectl get pods
  10. Убедитесь, что в поле EXTERNAL-IP сервиса myapp-service назначен публичный IP-адрес:

    kubectl get svc env-app-service

    Назначение публичного адреса занимает около пяти минут.

  11. Чтобы проверить работоспособность приложения и доступ к нему извне, в командной строке выполните:

    curl http://<EXTERNAL_IP> && echo

    Отобразится значение переменной APP_MESSAGE, указанное в файле configmap.yaml:

    "Hello from Kubernetes!"

    Таким образом вы убедились в работоспособности приложения, которое возвращает значения переменной из ConfigMap.

  12. Удалите созданные сущности Kubernetes:

    kubectl delete svc env-app-service
    kubectl delete configmap env-app-config
    kubectl delete deployment env-app

9. Подготовьте Helm-чарт с ранее развернутым приложением к работе

  1. В каталоге my-lab создайте базовую структуру Helm-чарта:

    helm create myapp-chart
  2. Перейдите в каталог myapp-chart и из каталога templates удалите лишние файлы:

  3. В каталоге myapp-chart создайте файл values.yaml:

    nano values.yaml
  4. В values.yaml добавьте содержимое:

    # Название приложения и параметры
    appName: env-app
    replicaCount: 2
    # Настройки образа
    image:
    repository: <yourproject_registry>.cr.cloud.ru/my-app
    tag: "1.0"
    pullPolicy: IfNotPresent
    # Настройки сервиса
    service:
    name: env-app-service
    type: LoadBalancer
    port: 80
    targetPort: 5000
    # Настройки ConfigMap
    configmap:
    name: env-app-config
    appMessage: "Hello from Helm!"
    # Метки приложения
    labels:
    app: env-app

    Где <yourproject_registry> — название вашего реестра в Artifact Registry.

  5. Создайте файл templates/configmap.yaml:

    nano templates/configmap.yaml
  6. В configmap.yaml добавьте следующее содержимое:

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: {{ .Values.configmap.name }}
    labels:
    app: {{ .Values.labels.app }}
    data:
    APP_MESSAGE: {{ .Values.configmap.appMessage | quote }}
  7. Создайте файл templates/deployment.yaml:

    nano templates/deployment.yaml
  8. В deployment.yaml добавьте следующее содержимое:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    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_MESSAGE
    valueFrom:
    configMapKeyRef:
    name: {{ .Values.configmap.name }}
    key: APP_MESSAGE
  9. Создайте файл templates/service.yaml:

    nano templates/service.yaml
  10. В service.yaml добавьте следующее содержимое:

    apiVersion: v1
    kind: Service
    metadata:
    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 }}
  11. Проверьте синтаксис чарта:

    helm lint .

10. Разверните приложение с помощью Helm-чарта

  1. Перейдите в каталог myapp-chart и разверните приложение:

    cd ~/my-lab/myapp-chart
    helm install myapp .
  2. Проверьте, что поды запущены и находятся в статусе «Running»:

    kubectl get pods
  3. Убедитесь, что для сервиса env-app-service назначен внешний IP-адрес EXTERNAL-IP:

    kubectl get svc env-app-service

    Назначение внешнего IP-адреса занимает около пяти минут.

  4. Проверьте вывод значения переменной APP_MESSAGE:

    curl http://<EXTERNAL_IP> && echo

    В консольной строке вы увидите значение:

    Hello from Helm!
  5. Внесите изменения в файл values.yaml, изменив поле appMessage в разделе configmap и количество реплик:

    # Название приложения и параметры
    appName: env-app
    replicaCount: 4
    # Настройки образа
    image:
    repository: <yourproject_registry>.cr.cloud.ru/my-app
    tag: "1.0"
    pullPolicy: IfNotPresent
    # Настройки сервиса
    service:
    name: env-app-service
    type: LoadBalancer
    port: 80
    targetPort: 5000
    # Настройки ConfigMap
    configmap:
    name: env-app-config
    appMessage: "Hello from Helm! - Updated version"
    # Метки приложения
    labels:
    app: env-app

    Где <yourproject_registry> — название вашего реестра в Artifact Registry.

  6. Обновите Helm-чарт и проверьте значение переменной окружения в выводе APP_MESSAGE:

    helm upgrade myapp .
    curl http://<EXTERNAL_IP> && echo

    Теперь в консольной строке вы увидите значение:

    Hello from Helm! - Updated version
  7. Проверьте, что в статусе «Running» теперь четыре пода:

    kubectl get pods

    При обновлении Helm-чарта были автоматически отмасштабированы и перезапущены поды приложения. Теперь они выводят обновленное значение переменной окружения APP_MESSAGE.

11. Проверьте механизм отката версии приложения Helm Rollback

  1. В values.yaml измените тег на несуществующий:

    # Название приложения и параметры
    appName: env-app
    replicaCount: 4
    # Настройки образа
    image:
    repository: <yourproject_registry>.cr.cloud.ru/my-app
    tag: "broken image"
    pullPolicy: IfNotPresent
    # Настройки сервиса
    service:
    name: env-app-service
    type: LoadBalancer
    port: 80
    targetPort: 5000
    # Настройки ConfigMap
    configmap:
    name: env-app-config
    appMessage: "Hello from Helm! - Updated version"
    # Метки приложения
    labels:
    app: env-app

    Где <yourproject_registry> — название вашего реестра в Artifact Registry.

  2. Обновите helm-чарт:

    helm upgrade myapp .

    Новые поды не смогут скачать образ.

  3. Убедитесь, что поды находятся в статусе «ImagePullBackOff» или «ErrImagePull»:

    kubectl get pods
  4. Откатите приложение на предыдущую версию и проверьте статус подов.

    helm rollback myapp
    kubectl get pods

    Они должны быть в статусе «Running».

  5. Проверьте вывод значения переменной APP_MESSAGE:

    curl http://<EXTERNAL_IP> && echo

    Приложение выводит значение переменной:

    Hello from Helm! - Updated version

    Откат приложения прошел успешно.

  6. Удалите приложение, запущенное через Helm-chart:

    helm uninstall myapp

12. Добавьте образ приложения Helm-chart в Artifact Registry и разверните приложение из реестра

  1. Внесите изменения в файл values.yaml:

    # Название приложения и параметры
    appName: env-app
    replicaCount: 4
    # Настройки образа
    image:
    repository: <yourproject_registry>.cr.cloud.ru/my-app
    tag: "1.0"
    pullPolicy: IfNotPresent
    # Настройки сервиса
    service:
    name: env-app-service
    type: LoadBalancer
    port: 80
    targetPort: 5000
    # Настройки ConfigMap
    configmap:
    name: env-app-config
    appMessage: "This Application is installed from the Artifact Registry helm-chart image"
    # Метки приложения
    labels:
    app: env-app

    Где <yourproject_registry> — название вашего реестра в Artifact Registry.

  2. Упакуйте Helm-чарт в архив .tgz:

    cd ~/my-lab
    helm package myapp-chart/. --version 1.0.0
  3. Загрузите упакованный чарт в OCI-реестр:

    helm push myapp-chart-1.0.0.tgz oci://<yourproject_registry>.cr.cloud.ru

    Где <yourproject_registry> — название вашего реестра в Artifact Registry.

  4. Запустите 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.

  5. Убедитесь, что поды находятся в статусе «Running» и дождитесь получения External-IP:

    kubectl get pods
    kubectl get svc env-app-service

    Назначение публичного адреса занимает около пяти минут.

  6. Проверьте вывод значения переменной APP_MESSAGE:

    curl http://<EXTERNAL_IP> && echo

Результат

Вы научились:

  • работать с YAML-манифестами в Kubernetes;

  • запускать и откатывать версии приложения с помощью Helm-чартов;

  • загружать и скачивать образы Helm-чартов из Artifact Registry.