Непрерывное развертывание контейнеризованных приложений с помощью GitLab

GitLab — инструмент непрерывной интеграции. В сценарии описано, как выполнять сборку приложения в Docker-контейнер и развертывать приложение из контейнера на кластере Kubernetes через GitLab с помощью инструментов Яндекс.Облака. После каждого коммита в GitLab будет выполняться сценарий, в котором описаны шаги сборки Docker-образа и применение новой конфигурации Kubernetes-кластера, в которой будет указано приложение для развертывания. Чтобы настроить необходимую инфраструктуру для хранения исходного кода, сборки Docker-образа и развертывания приложения, выполните следующие шаги:

Если созданные ВМ и кластер больше не нужны, удалите их.

Подготовьте облако к работе

Перед работой нужно зарегистрироваться в Облаке и создать платежный аккаунт:

  1. Перейдите в консоль управления, затем войдите в Яндекс.Облако или зарегистрируйтесь, если вы еще не зарегистрированы.
  2. На странице биллинга убедитесь, что у вас подключен платежный аккаунт, и он находится в статусе ACTIVE или TRIAL_ACTIVE. Если платежного аккаунта нет, создайте его.

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

Подробнее об облаках и каталогах.

В стоимость поддержки инфраструктуры входят:

Установите дополнительные зависимости

Для выполнения сценария установите в локальном окружении:

Создайте виртуальную машину из образа GitLab

Запустите GitLab на виртуальной машине с публичным IP-адресом:

  1. На странице каталога в консоли управления нажмите кнопку Создать ресурс и выберите Виртуальная машина.

  2. В поле Имя введите имя виртуальной машины: ci-tutorial-gitlab.

  3. Выберите зону доступности, в которой будет находиться виртуальная машина.

  4. В разделе Образы нажмите кнопку Выбрать.

  5. В открывшемся окне перейдите на вкладку DevTools.

  6. Выберите образ GitLab.

  7. В блоке Вычислительные ресурсы укажите следующую конфигурацию:

    • vCPU2
    • Гарантированная доля vCPU100%
    • RAM2 ГБ
  8. В блоке Сетевые настройки выберите, к какой подсети подключить виртуальную машину. Если нужной сети или подсети еще нет, вы можете создать их прямо на странице создания ВМ.

  9. В поле Публичный адрес укажите Автоматически.

  10. Укажите данные для доступа на виртуальную машину:

    • В поле Логин введите имя пользователя.
    • В поле SSH ключ скопируйте содержимое файла открытого ключа. Пару ключей для подключения по SSH необходимо создать самостоятельно. Для создания ключей используйте сторонние инструменты, например утилиты ssh-keygen в Linux и macOS или PuTTYgen в Windows.
  11. Нажмите кнопку Создать ВМ.

Создание виртуальной машины может занять несколько минут. Когда виртуальная машина перейдет в статус RUNNING и запустится GitLab, вы можете перейти к его настройке.

Создайте реестр Container Registry

Для хранения Docker-образов вам понадобится реестр Container Registry.

Чтобы создать реестр:

  1. На странице каталога в консоли управления выберите Container Registry.
  2. Нажмите кнопку Создать реестр.
  3. Задайте имя реестра.

Сохраните идентификатор реестра — он понадобится для следующих шагов.

Настройте GitLab

Чтобы настроить GitLab и подготовить процесс непрерывной интеграции (Continuous Integration, CI), создайте новый проект и введите параметры для авторизации в CI:

  1. На странице сервиса Compute Cloud выберите созданную виртуальную машину и найдите ее публичный IP-адрес.
  2. Откройте в браузере ссылку http://<публичный IP-адрес ВМ>. Откроется административная панель GitLab.
  3. Задайте пароль администратора и нажмите кнопку Change your password.
  4. Введите логин root и пароль администратора. Нажмите кнопку Sign in.
  5. Выберите Create a project.
  6. Задайте имя проекта: gitlab-test.
  7. Нажмите кнопку Create project.

Создайте тестовое приложение

Создайте тестовое приложение, которое можно будет развернуть в Kubernetes кластере:

  1. Добавьте конфигурацию Docker-образа

    1. На левой панели в GitLab перейдите в раздел Project и выберите вкладку Details.

    2. На странице проекта нажмите кнопку New file.

    3. Назовите файл Dockerfile. Добавьте в него конфигурацию Docker-образа:

      FROM alpine:3.10
      CMD echo "Hello"
      
    4. Напишите комментарий к коммиту в поле Commit message: Dockerfile for test application.

    5. Нажмите кнопку Commit changes.

  2. Добавьте конфигурацию для разворачивания Docker-образа в Kubernetes-кластере:

    1. В панели слева перейдите в раздел Project и выберите вкладку Details.

    2. Справа от имени проекта нажмите кнопку + и в выпадающем меню выберите пункт New file.

    3. Назовите файл k8s.yaml. Добавьте в него конфигурацию создания namespace и deployment:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: hello-world
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: hello-world-deployment
        namespace: hello-world
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: hello
        template:
          metadata:
            namespace: hello-world
            labels:
              app: hello
          spec:
            containers:
              - name: hello-world
                image: cr.yandex/<ID реестра>/hello:__VERSION__
                imagePullPolicy: Always
      
    4. Замените в приведенном файле <ID реестра> на идентификатор вашего реестра, созданного ранее.

    5. Напишите комментарий к коммиту в поле Commit message: Docker image deployment config.

    6. Нажмите кнопку Commit changes.

Создайте ресурсы Kubernetes

Для выполнения сценариев создайте необходимые ресурсы Kubernetes: кластер и группу узлов.

  1. Если у вас еще нет сети, создайте ее.

  2. Если у вас еще нет подсетей, создайте их в зонах доступности, где будут созданы кластер Kubernetes и группа узлов.

  3. Создайте сервисные аккаунты:

    • Сервисный аккаунт для ресурсов с ролью editor на каталог, в котором создается кластер Kubernetes. От его имени будут создаваться ресурсы, необходимые кластеру Kubernetes.
    • Сервисный аккаунт для узлов с ролью container-registry.images.pusher на каталог с реестром Docker-образов. От его имени узлы будут загружать в реестр собранные в GitLab Docker-образы.

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

Создайте кластер

Чтобы создать кластер Kubernetes:

  1. В консоли управления выберите каталог, в котором будет создан кластер Kubernetes.
  2. В списке сервисов выберите Managed Service for Kubernetes.
  3. Нажмите кнопку Создать кластер.
  4. Введите имя и описание кластера Kubernetes.
  5. Укажите Сервисный аккаунт для ресурсов, который будет использоваться для создания ресурсов.
  6. Укажите Сервисный аккаунт для узлов, который будет использоваться узлами для доступа к реестру Docker-образов.
  7. Укажите релизный канал.
  8. В блоке Конфигурация мастера:
    • В поле Версия Kubernetes выберите версию Kubernetes, которая будет установлена на мастере.

    • В поле Публичный адрес выберите способ назначения адреса:

      • Автоматически — чтобы назначить случайный IP-адрес из пула адресов Яндекс.Облака.
      • Без адреса — чтобы не назначать публичный IP-адрес.
    • В поле Тип мастера выберите тип мастера:

      • Зональный — создается в подсети в одной зоне доступности.
      • Региональный — создается распределенно в трех подсетях в каждой зоне доступности.
    • Выберите зону доступности, в которой будет создан мастер.

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

    • В поле Формат сети выберите способ отображения сетей:

      • Список — отображается список доступных сетей. Если у вас нет облачной сети, нажмите кнопку Создать сеть:
        • В открывшемся окне задайте имя сети. Укажите, что необходимо создать подсети. Нажмите кнопку Создать сеть. По умолчанию будет создана сеть с подсетями в каждой зоне доступности.
      • ID — необходимо ввести уникальные идентификаторы необходимых сетей.
    • В поле Облачная сеть выберите сеть, в которой будет создан мастер.

    • В поле Подсеть выберите подсеть, в которой будет создан мастер.

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

  9. В блоке Настройки окна обновлений:
    • В поле Частота обновлений / Отключение настройте окно для обновлений:
      • Отключено — отключение автоматических обновлений.
      • В любое время — обновления разрешены в любое время.
      • Ежедневно — обновления будут происходить во временном интервале, указанном в поле Время (UTC) и продолжительность.
      • В выбранные дни — обновления будут происходить во временном интервале, указанном в поле Время (UTC) и продолжительность.
  10. В блоке Сетевые настройки кластера:
    • Укажите CIDR кластера — диапазон IP-адресов, из которого будут выделяться IP-адреса для подов.
    • Укажите CIDR сервисов — диапазон IP-адресов, из которого будут выделяться IP-адреса для сервисов.
  11. Нажмите кнопку Создать кластер.

Сохраните идентификатор кластера - он понадобится для следующих шагов.

Создайте группу узлов

Создание кластера Kubernetes может занять несколько минут. Когда созданный кластер перейдет в статус RUNNING, вы можете перейти к создание группы узлов в этом кластере.

Чтобы создать группу узлов:

  1. В консоли управления выберите каталог, в котором будет создан кластер Kubernetes.
  2. В списке сервисов выберите Managed Service for Kubernetes.
  3. Выберите кластер Kubernetes, для которого необходимо создать группу узлов.
  4. На странице кластера Kubernetes перейдите на вкладку Группы узлов.
  5. Нажмите кнопку Создать группу узлов.
  6. Введите имя и описание группы узлов.
  7. Укажите количество узлов в группе узлов.
  8. Укажите версию Kubernetes для узлов.
  9. В блоке Вычислительные ресурсы:
  10. В блоке Хранилище:
    • Укажите Тип диска узла:
      • HDD — стандартный сетевой диск, сетевое блочное хранилище на HDD-накопителе.
      • SSD — быстрый сетевой диск, сетевое блочное хранилище на SSD-накопителе.
    • Укажите размер диска узла.
  11. В блоке Сетевые настройки:
    • В поле Публичный адрес выберите способ назначения адреса:
      • Автоматически — чтобы назначить случайный IP-адрес из пула адресов Яндекс.Облака.
      • Без адреса — чтобы не назначать публичный IP-адрес.
    • Укажите расположение узлов по зонам доступности и сетям.
    • (опционально) Нажмите кнопку Добавить расположение и укажите дополнительную зону доступности и сеть, чтобы создать узлы в разных зонах доступности.
  12. В блоке Доступ укажите данные для доступа на узел:
    • В поле Логин введите имя пользователя.
    • В поле SSH-ключ вставьте содержимое файла публичного ключа.
  13. В блоке Настройки обновлений, UTC:
    • В поле Окно обновлений выберите окно для обновлений:
      • Отключено — отключение автоматических обновлений.
      • В любое время — обновления разрешены в любое время.
      • Ежедневно — обновления будут происходить во временной интервал, указанный в поле Время и продолжительность.
      • В выбранные дни — обновления будут происходить во временной интервал, указанный в поле Время и продолжительность.
  14. Нажмите кнопку Создать группу узлов.

Получите токен сервисного аккаунта Kubernetes для аутентификации в GitLab

Примечание

Обратите внимание, что сервисный аккаунт Kubernetes — это не сервисный аккаунт IAM.

Чтобы получить токен сервисного аккаунта Kubernetes:

  1. Настройте локальное окружение на работу с созданным кластером Kubernetes. Для этого выполните команду:

    $ yc managed-kubernetes cluster get-credentials <cluster-id> --external
    
  2. Сохраните спецификацию для создания сервисного аккаунта Kubernetes в YAML-файл gitlab-admin-service-account.yaml:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: gitlab-admin
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: gitlab-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - kind: ServiceAccount
      name: gitlab-admin
      namespace: kube-system
    
  3. Выполните команду:

    $ kubectl apply -f gitlab-admin-service-account.yaml
    
  4. Узнайте токен с помощью команды kubectl get secrets:

    $ kubectl -n kube-system get secrets -o json | \
    jq -r '.items[] | select(.metadata.name | startswith("gitlab-admin")) | .data.token' | \
    base64 --decode
    
  5. Сохраните полученный токен — он понадобится для следующих шагов.

Подключите кластер Kubernetes к сборкам GitLab

Для того, чтобы запускать задачи сборки на кластере Kubernetes, подключите кластер в настройках GitLab.

  1. Откройте в браузере ссылку вида http://<публичный IP-адрес ВМ GitLab>/root.

  2. Выберите проект с именем gitlab-test.

  3. В открывшемся окне слева нажмите на Operations и выберите пункт Kubernetes.

  4. Нажмите кнопку Add Kubernetes cluster.

  5. В открывшемся окне нажмите Add existing cluster.

  6. В поле Kubernetes cluster name введите имя кластера.

  7. В поле API URL введите адрес узла мастера. Узнайте его с помощью команды:

    $ yc managed-kubernetes cluster get <cluster-id> --format=json \
    | jq -r .master.endpoints.external_v4_endpoint
    
  8. В поле CA Certificate введите сертификат мастера. Узнайте его с помощью команды:

    $ yc managed-kubernetes cluster get <cluster-id> --format=json \
    | jq -r .master.master_auth.cluster_ca_certificate
    
  9. В поле Service Token введите токен, который GitLab будет использовать для создания ресурсов Kubernetes. Используйте токен, полученный перед началом работы.

  10. Нажмите кнопку Add Kubernetes cluster.

  11. Установите на кластер Kubernetes приложения, необходимые для корректной работы GitLab Runner:

    • Напротив надписи Helm Tiller нажмите кнопку Install.
    • Напротив надписи GitLab Runner нажмите кнопку Install.

Теперь вы можете запускать автоматизированные сборки внутри своего Kubernetes-кластера.

Подробнее про настройки подключения кластера Kubernetes к сборкам GitLab читайте в документации GitLab.

Настройте сборку и развертывание Docker-образа из CI

  1. Создайте переменные окружения GitLab.

    1. В GitLab в панели слева перейдите в раздел Settings и во всплывающем списке выберите пункт CI/CD.
    2. Нажмите кнопку Expand напротив пункта Variables.
    3. Добавьте две переменные окружения:
      • KUBE_URL – адрес мастера. Узнайте его с помощью команды:

        $ yc managed-kubernetes cluster get <cluster-id> --format=json \
        | jq -r .master.endpoints.external_v4_endpoint
        
      • KUBE_TOKEN – токен, который будет использовать GitLab для применения конфигурации. Используйте токен, полученный перед началом работы.

    4. Нажмите кнопку Save variables.
  2. GitLab позволяет настраивать сценарии сборки в YAML-файле. Создайте файл конфигурации .gitlab-ci.yml:

    1. В GitLab в панели слева перейдите в раздел Project и выберите вкладку Details.
    2. Справа от имени проекта нажмите кнопку + и в выпадающем меню выберите пункт New file.
    3. Назовите файл .gitlab-ci.yml. Добавьте в него шаги сборки и загрузки Docker-образа и обновления Kubernetes-кластера:
    stages:
      - build
      - deploy
      
    build:
      stage: build
      variables:
        DOCKER_DRIVER: overlay2
        DOCKER_TLS_CERTDIR: ""
        DOCKER_HOST: tcp://localhost:2375/
      image: cr.yandex/yc/metadata-token-docker-helper:0.2
      services:
        - docker:19.03.1-dind
      script:
        - docker build . -t cr.yandex/<ID реестра>/hello:gitlab-$CI_COMMIT_SHORT_SHA
        - docker push cr.yandex/<ID реестра>/hello:gitlab-$CI_COMMIT_SHORT_SHA
          
    deploy:
      image: gcr.io/cloud-builders/kubectl:latest
      stage: deploy
      script:
        - kubectl config set-cluster k8s --server="$KUBE_URL" --insecure-skip-tls-verify=true
        - kubectl config set-credentials admin --token="$KUBE_TOKEN"
        - kubectl config set-context default --cluster=k8s --user=admin
        - kubectl config use-context default
        - sed -i "s/__VERSION__/gitlab-$CI_COMMIT_SHORT_SHA/" k8s.yaml
        - kubectl apply -f k8s.yaml
    
    1. Замените в приведенном файле <ID реестра> на идентификатор вашего реестра, созданного ранее.
    2. Напишите комментарий к коммиту в поле Commit message: CI scripts.
    3. Нажмите кнопку Commit changes.

    Примечание

    В файле .gitlab-ci.yml описаны два шага сборки проекта:

    • Сборка Docker-образа с использованием Dockerfile из предыдущего этапа и загрузка образа в Container Registry.
      • Для этого шага нужно использовать контейнер для сборки Docker-образов и запустить Docker-сервер как GitLab-сервис.
      • Для аутентификации в Container Registry нужно использовать сервисный аккаунт, подключенный к узлам Kubernetes. В начале работы этому аккаунту была назначена роль container-registry.images.pusher.
      • Чтобы получить из метаданных ВМ данные для аутентификации, используется вспомогательный публичный Docker-образ cr.yandex/yc/metadata-token-docker-helper:0.2. Внутри него работает Docker credential helper, который получает IAM-токен из сервиса метаданных.
    • Настройка окружения для работы с Kubernetes и применение конфигурации k8s.yaml к кластеру Kubernetes. Таким образом приложение развертывается на созданном ранее кластере.
  3. После сохранения файла должен запуститься сценарий сборки. Посмотреть на его исполнение можно на вкладке слева CI/CD, выбрав в выпадающем меню пункт Pipelines. Дождитесь успешного завершения обоих этапов сборки.

  4. Проверьте результат, посмотрев логи контейнера в Kubernetes кластере:

$ kubectl logs deployment/hello-world-deployment -n hello-world

Hello

Удалите созданные ресурсы

Если вам больше не нужны развернутые приложения и кластер Kubernetes:

См. также