Непрерывное развертывание контейнеризованных приложений с помощью GitLab
GitLab
В этом руководстве описаны:
- Сборка приложения в Docker-контейнер.
- Развертывание приложения из контейнера в кластере Yandex Managed Service for Kubernetes через GitLab с помощью инструментов Yandex Cloud.
После каждого коммита в GitLab:
- Выполнится сценарий, в котором описаны шаги сборки Docker-образа.
- Применится новая конфигурация кластера Managed Service for Kubernetes, в которой будет указано приложение для развертывания.
Чтобы настроить необходимую инфраструктуру для хранения исходного кода, сборки Docker-образа и развертывания приложения:
Если созданные ресурсы больше не нужны, удалите их.
Подготовьте облако к работе
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVE
илиTRIAL_ACTIVE
. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость поддержки инфраструктуры входит плата за следующие ресурсы:
- Диски и постоянно запущенные виртуальные машины (см. тарифы Yandex Compute Cloud).
- Использование динамического публичного IP-адреса (см. тарифы Yandex Virtual Private Cloud).
- Хранение созданных Docker-образов (см. тарифы Container Registry).
- Использование мастера Managed Service for Kubernetes (см. тарифы Managed Service for Kubernetes).
Подготовьте инфраструктуру
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра --folder-name
или --folder-id
.
-
Если у вас еще нет сети, создайте ее.
-
Если у вас еще нет подсетей, создайте их в зонах доступности, где будут созданы кластер Yandex Managed Service for Kubernetes и группа узлов.
-
- Для ресурсов с ролью editor на каталог, в котором создается кластер Managed Service for Kubernetes. От его имени будут создаваться ресурсы, необходимые кластеру Managed Service for Kubernetes.
- Для узлов с ролями container-registry.images.puller и container-registry.images.pusher на каталог с реестром Docker-образов. От его имени узлы Managed Service for Kubernetes будут загружать в реестр собранные в GitLab Docker-образы, а также скачивать их для запуска подов.
Совет
Вы можете использовать один и тот же сервисный аккаунт для обеих операций.
-
Создайте группы безопасности для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
Создайте группу безопасности для работы инстанса Managed Service for GitLab.
-
Создайте кластер Managed Service for Kubernetes и группу узлов. При создании кластера Managed Service for Kubernetes укажите ранее созданные сервисные аккаунты для ресурсов и узлов и группы безопасности.
-
Создайте авторизованный ключ для сервисного аккаунта с ролью
container-registry.images.pusher
и сохраните в файлkey.json
:yc iam key create \ --service-account-name <имя_сервисного_аккаунта> \ --output key.json
Ключ необходим для доступа к реестру из GitLab.
-
Если у вас еще нет Terraform, установите его.
-
Получите данные для аутентификации. Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
-
Настройте и инициализируйте провайдер. Чтобы не создавать конфигурационный файл с настройками провайдера вручную, скачайте его
. -
Поместите конфигурационный файл в отдельную рабочую директорию и укажите значения параметров. Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.
-
Скачайте в ту же рабочую директорию файл конфигурации k8s-and-registry-for-gitlab.tf
.В этом файле описаны:
-
Сеть.
-
Сервисный аккаунт, необходимый для работы кластера Managed Service for Kubernetes и группы узлов.
-
Группы безопасности, которые содержат необходимые правила для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
Группа безопасности по умолчанию и правила, необходимые для работы инстанса Managed Service for GitLab.
-
Авторизованный ключ для сервисного аккаунта. Ключ необходим для доступа к реестру из GitLab.
-
Локальный файл
key.json
с данными авторизованного ключа.
-
-
Укажите в файле
k8s-and-registry-for-gitlab.tf
:- Идентификатор каталога.
- Версию Kubernetes для кластера Managed Service for Kubernetes и групп узлов.
- Имя сервисного аккаунта кластера Managed Service for Kubernetes.
- Имя реестра Container Registry.
-
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validate
Если в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Создайте необходимую инфраструктуру:
-
Выполните команду для просмотра планируемых изменений:
terraform plan
Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в консоли управления
. -
Важно
Для реальных приложений доступ сервисных аккаунтов кластера Managed Service for Kubernetes к загрузке Docker-образов в реестр должен быть ограничен по соображениям безопасности. В этом случае создайте отдельный сервисный аккаунт с ролью container-registry.images.pusher
и указывайте его для развертывания приложений.
Установите дополнительные зависимости
Установите в локальном окружении:
- Утилиту потоковой обработки JSON-файлов
jq
. - Инструмент командной строки kubectl
и настройте его на работу с созданным кластером Managed Service for Kubernetes.
Создайте инстанс GitLab
Создайте инстанс Managed Service for GitLab или виртуальную машину с образом GitLab в той же облачной сети, где расположен кластер Managed Service for Kubernetes.
Создайте инстанс Managed Service for GitLab согласно инструкции.
Запустите GitLab на ВМ с публичным IP-адресом.
-
На странице каталога в консоли управления
нажмите кнопку Создать ресурс и выберитеВиртуальная машина
. -
В блоке Образ загрузочного диска в поле Поиск продукта введите
Gitlab
и выберите публичный образ GitLab. -
В блоке Расположение выберите зону доступности, в которой будет находиться ВМ. Если вы не знаете, какая зона доступности вам нужна, оставьте выбранную по умолчанию.
-
В блоке Вычислительные ресурсы перейдите на вкладку
Своя конфигурация
и укажите необходимую платформу, количество vCPU и объем RAM:- Платформа —
Intel Ice Lake
. - vCPU —
4
. - Гарантированная доля vCPU —
100%
. - RAM —
8 ГБ
.
- Платформа —
-
В блоке Сетевые настройки:
- В поле Подсеть выберите сеть и подсеть, к которым нужно подключить ВМ. Если нужной сети или подсети еще нет, создайте их.
- В поле Публичный адрес оставьте значение
Автоматически
, чтобы назначить ВМ случайный внешний IP-адрес из пула Yandex Cloud, или выберите статический адрес из списка, если вы зарезервировали его заранее.
-
В блоке Доступ выберите вариант SSH-ключ и укажите данные для доступа на ВМ:
- В поле Логин введите имя пользователя. Не используйте имя
root
или другие имена, зарезервированные ОС. Для выполнения операций, требующих прав суперпользователя, используйте командуsudo
. -
В поле SSH-ключ выберите SSH-ключ, сохраненный в вашем профиле пользователя организации.
Если в вашем профиле нет сохраненных SSH-ключей или вы хотите добавить новый ключ:
- Нажмите кнопку Добавить ключ.
- Задайте имя SSH-ключа.
- Загрузите или вставьте содержимое открытого SSH-ключа. Пару SSH-ключей для подключения к ВМ по SSH необходимо создать самостоятельно.
- Нажмите кнопку Добавить.
SSH-ключ будет добавлен в ваш профиль пользователя организации.
Если в организации отключена возможность добавления пользователями SSH-ключей в свои профили, добавленный открытый SSH-ключ будет сохранен только в профиле пользователя создаваемой виртуальной машины.
- В поле Логин введите имя пользователя. Не используйте имя
-
В блоке Общая информация задайте имя ВМ:
ci-tutorial-gitlab
. -
Нажмите кнопку Создать ВМ.
Создание ВМ может занять несколько минут. Когда ВМ перейдет в статус RUNNING
и запустится GitLab, настройте его.
Настройте GitLab
Чтобы настроить GitLab и подготовить процесс непрерывной интеграции (Continuous Integration, CI), создайте новый проект и введите параметры для авторизации в CI:
-
Авторизуйтесь в веб-интерфейсе инстанса Managed Service for GitLab.
-
Нажмите кнопку Create a project.
-
Нажмите кнопку Create blank project.
-
Заполните поля:
- Project name —
gitlab-test
. - Project URL — выберите пользователя-администратора в поле рядом с FQDN инстанса Managed Service for GitLab.
Остальные поля оставьте без изменений.
- Project name —
-
Нажмите кнопку Create project.
-
На странице сервиса Yandex Compute Cloud выберите созданную ВМ и скопируйте ее публичный IP-адрес.
-
Подключитесь к ВМ по протоколу SSH.
-
Получите пароль администратора GitLab с помощью команды ВМ:
sudo cat /etc/gitlab/initial_root_password
-
Скопируйте пароль из строки
Password
(исключая пробелы) в буфер обмена или отдельный файл. -
Откройте в браузере ссылку
http://<публичный_IP-адрес_ВМ>
. Откроется веб-интерфейс GitLab. -
Войдите в систему с учетной записью администратора:
- Username or email —
root
. - Password — пароль, скопированный ранее.
Если вы не можете войти, сбросьте пароль учетной записи администратора
. - Username or email —
-
Повторно войдите в систему с учетной записью администратора, используя новый пароль.
-
Выберите Create a project.
-
Задайте имя проекта:
gitlab-test
. -
Нажмите кнопку Create project.
Создайте тестовое приложение
Создайте тестовое приложение, которое можно будет развернуть в кластере Yandex Managed Service for Kubernetes:
- Добавьте в проект
Dockerfile
:-
Авторизуйтесь в GitLab.
-
Откройте проект GitLab.
-
В строке навигации по репозиторию нажмите кнопку
и в выпадающем меню выберите пункт New file. -
Назовите файл
Dockerfile
и добавьте в него код:FROM alpine:3.10 CMD echo "Hello"
-
Напишите комментарий к коммиту в поле Commit message:
Dockerfile for test application
. -
Нажмите кнопку Commit changes.
-
- Добавьте в проект манифест создания ресурсов кластера Managed Service for Kubernetes:
-
Откройте проект GitLab.
-
В строке навигации по репозиторию нажмите кнопку
и в выпадающем меню выберите пункт New file. -
Назовите файл
k8s.yaml
:k8s.yaml
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: __VERSION__ imagePullPolicy: Always
-
Напишите комментарий к коммиту в поле Commit message:
Docker image deployment config
. -
Нажмите кнопку Commit changes.
-
Создайте GitLab Runner
Чтобы запускать задачи сборки в кластере Yandex Managed Service for Kubernetes, создайте GitLab Runner
После установки вы можете запускать автоматизированные сборки внутри своего кластера Managed Service for Kubernetes.
Подробнее про установку и настройку GitLab Runner читайте в документации GitLab
Настройте аутентификацию Kubernetes в GitLab
Настроить аутентификацию в GitLab можно с помощью токена сервисного аккаунта Kubernetes или приложения GitLab Agent:
Примечание
Чтобы получить токен сервисного аккаунта Kubernetes:
- Создайте сервисный аккаунт.
- Получите токен сервисного аккаунта.
- Сохраните полученный токен — он понадобится для следующих шагов.
Чтобы подключить кластер Yandex Managed Service for Kubernetes к GitLab, создайте GitLab Agent
После установки вы можете подключать кластер Managed Service for Kubernetes к инстансу GitLab.
Подробнее про установку и настройку GitLab Agent читайте в документации GitLab
Настройте сценарий CI
-
Создайте переменные окружения GitLab
:-
На панели слева в GitLab перейдите в раздел Settings и во всплывающем списке выберите пункт CI/CD.
-
Нажмите кнопку Expand напротив пункта Variables.
-
Добавьте переменные окружения в зависимости от способа аутентификации Kubernetes в GitLab:
Токен сервисного аккаунтаGitLab Agent-
KUBE_URL
— адрес мастера Managed Service for Kubernetes. Узнайте его с помощью команды:yc managed-kubernetes cluster get <идентификатор_или_имя_кластера> --format=json \ | jq -r .master.endpoints.external_v4_endpoint
-
KUBE_TOKEN
— токен, который GitLab будет использовать для применения конфигурации. Используйте токен, полученный ранее.
CI_REGISTRY
— адрес созданного ранее реестра в форматеcr.yandex/<идентификатор_реестра>
.CI_REGISTRY_KEY
— ключ, который GitLab будет использовать для доступа к реестру. Скопируйте содержимое файла статического ключаkey.json
для доступа к реестру, полученного ранее.
Для добавления переменной:
- Нажмите кнопку Add variable.
- В появившемся окне в поле Key укажите имя переменной, в поле Value — значение переменной.
- Нажмите кнопку Add variable.
-
-
-
Создайте файл конфигурации сценария CI:
-
Откройте проект
gitlab-test
. -
В строке навигации по репозиторию нажмите кнопку
и в выпадающем меню выберите пункт New file. -
Назовите файл
.gitlab-ci.yml
. Добавьте в него шаги сборки и загрузки Docker-образа и обновления конфигурации приложения в кластере Managed Service for Kubernetes. Структура файла зависит от способа аутентификации Kubernetes в GitLab:Токен сервисного аккаунтаGitLab Agent-
Для сборки контейнера с помощью
kaniko
без использования привилегированного режима GitLab Runner:.gitlab-ci.yml
stages: - build - deploy build: stage: build image: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(echo -n "json_key:${CI_REGISTRY_KEY}" | base64 | tr -d '\n' )\"}}}" > /kaniko/.docker/config.json - >- /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY}/${CI_PROJECT_PATH}:${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__,${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}," k8s.yaml - kubectl apply -f k8s.yaml
-
Для сборки контейнера с помощью
docker:dind
c использованием привилегированного режима GitLab Runner:.gitlab-ci.yml
stages: - build - deploy image: docker:20.10.16 variables: DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" DOCKER_DRIVER: overlay2 services: - docker:20.10.16-dind before_script: - for try in {1..10}; do sleep 0.5; docker info && break ; done build: stage: build script: - echo "${CI_REGISTRY_KEY}" | docker login ${CI_REGISTRY} -u json_key --password-stdin - >- docker build "${CI_PROJECT_DIR}" --file "${CI_PROJECT_DIR}/Dockerfile" --tag "${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}" - docker push "${CI_REGISTRY}/${CI_PROJECT_PATH}:${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__,${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}," k8s.yaml - kubectl apply -f k8s.yaml
-
Для сборки контейнера с помощью
kaniko
без использования привилегированного режима GitLab Runner:.gitlab-ci.yml
stages: - build - deploy build: stage: build image: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(echo -n "json_key:${CI_REGISTRY_KEY}" | base64 | tr -d '\n' )\"}}}" > /kaniko/.docker/config.json - >- /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}" deploy: image: bitnami/kubectl:latest stage: deploy script: - kubectl config use-context ${CI_PROJECT_PATH}:<имя_GitLab_Agent> - cat k8s.yaml | sed -e "s,__VERSION__,${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}," | kubectl apply -f -
-
Для сборки контейнера с помощью
docker:dind
с использованием привилегированного режима GitLab Runner:.gitlab-ci.yml
stages: - build - deploy image: docker:20.10.16 variables: DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" DOCKER_DRIVER: overlay2 services: - docker:20.10.16-dind before_script: - for try in {1..10}; do sleep 0.5; docker info && break ; done build: stage: build script: - echo "${CI_REGISTRY_KEY}" | docker login ${CI_REGISTRY} -u json_key --password-stdin - >- docker build "${CI_PROJECT_DIR}" --file "${CI_PROJECT_DIR}/Dockerfile" --tag "${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}" - docker push "${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}" deploy: image: bitnami/kubectl:latest stage: deploy script: - kubectl config use-context ${CI_PROJECT_PATH}:<имя_GitLab_Agent> - cat k8s.yaml | sed -e "s,__VERSION__,${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}," | kubectl apply -f -
Вместо
<имя_GitLab_Agent>
укажите имя агента в Managed Service for GitLab. -
-
Напишите комментарий к коммиту в поле Commit message:
CI scripts
. -
Нажмите кнопку Commit changes.
В файле
.gitlab-ci.yml
описаны два шага сборки проекта:- Сборка Docker-образа с использованием
Dockerfile
и загрузка образа в Container Registry. - Настройка окружения для работы с Kubernetes и применение конфигурации
k8s.yaml
к кластеру Managed Service for Kubernetes. Таким образом приложение развертывается на созданном ранее кластере Managed Service for Kubernetes.
-
Проверьте результат
-
После сохранения файла конфигурации
.gitlab-ci.yml
запустится сценарий сборки. Чтобы проверить результаты его выполнения, на панели слева в проектеgitlab-test
выберите пункт Build, в выпадающем меню выберите пункт Pipelines и дождитесь успешного завершения обоих этапов сборки. -
Чтобы проверить работу созданного приложения в кластере Managed Service for Kubernetes, посмотрите логи контейнера в кластере:
kubectl logs deployment/hello-world-deployment -n hello-world
Результат:
Hello
Удалите созданные ресурсы
Некоторые ресурсы платные. Удалите ресурсы, которые вы больше не будете использовать, во избежание списания средств за них:
-
Удалите кластер Managed Service for Kubernetes и реестр Container Registry:
ВручнуюTerraform-
В командной строке перейдите в директорию, в которой расположен актуальный конфигурационный файл Terraform с планом инфраструктуры.
-
Удалите конфигурационный файл
k8s-and-registry-for-gitlab.tf
. -
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validate
Если в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Подтвердите изменение ресурсов.
-
Выполните команду для просмотра планируемых изменений:
terraform plan
Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
Все ресурсы, которые были описаны в конфигурационном файле
k8s-and-registry-for-gitlab.tf
, будут удалены. -
-
-
Удалите созданную ВМ GitLab или инстанс Managed Service for GitLab.