01.07.2020 docker deploy gitlab ci-cd
Ранее мы рассматривали деплой бинарного файла программы через SSH на сервер
Сейчас мы рассмотрим как реализовать деплой Docker контейнера из Gitlab CI.
При использовании Docker существует множество плюсов сравнительно с деплоем бинарного файла:
docker. В то время, как для запуска бинарного файла
потребуется программы типа systemd или supervisor.
Ранее мы рассмотрели сборку минимально возможного образа с программой GO. Для сборки образа далее будем использовать данный подход.
Будем пользоваться только базовыми возможностями консольной команды docker,
намеренно не будем применять никакие оркестраторы вроде kubernetes,nomad;
не будем использовать облачные хостинги вроде Google Cloud — все это потребует
очень много дополнительных объяснений и будет рассмотрено отдельно.
Для деплоя будем использовать docker swarm, который входит в базовую функциональность
docker.
Swarm позволяет управлять запуском docker-контейнеров на удаленном сервере, на котором
заранее была выполнена команда docker swarm init (создание нового swarm) или
docker swarm join (подключение к существующему swarm).
После выполнения этих команд docker на текущем сервере переходит в swarm-режим.
Для деплоя в docker swarm нам не требуется SSH-доступ на сервер.
Команда docker stack deploy позволяет выполнить обновление docker-контейнеров
на сервере по конфигурационному файлу в формате docker-compose,
так что даже дополнительную утилиту docker-compose устанавливать не требуется.
Также именно при вызове docker stack deploy мы можем указать не только список контейнеров,
но также объединить несколько контейнеры в сервисы с масштабированием нагрузки по контейнерам внутри сервиса;
можем указать политику обновления контейнеров, те обеспечить production-ready деплой
с резервированием и без простоев. Данный способ деплоя является наилучшей альтернативой
при использовании лишь утилиты docker.
Необходимо зайти по SSH по сервер, на котором предполагается запуск контейнеров, и перевести docker-сервер в swarm режим:
docker swarm init
Данная команда также выведет токены для подключения других серверов к данному swarm с помощью команды
docker swarm join --token xxx
Однако, для такой работы нам потребуются другие серверы. Мы же будем работать всего с одним сервером.
Мы не будем использовать docker swarm join.
Изменим запуск docker-сервиса таким образом, чтобы сервер был доступен удаленно (не только с localhost).
Создадим или изменим файл службы docker для systemd:
sudo -s mkdir -p /etc/systemd/system/docker.service.d touch /etc/systemd/system/docker.service.d/startup_options.conf
Содержимое файла:
[Service] ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376
Перезапустим службу:
systemctl daemon-reload
Теперь Docker-сервис на данном сервере может принимать удаленные подключения.
Для деплоя docker стэка на удаленный сервер, работающий в swarm режиме, мы реализовали следующий шаг в .gitlab-ci.yml:
deploy_docker_stage:
environment:
name: stage
url: https://someurl
image: docker:19.03.1
services:
— docker:19.03.1-dind
stage: deploy
variables:
DOCKER_HOST: "tcp://${DOCKER_HOST}:2376"
before_script:
— apk add jq
— docker login -u $USER -p $PASSWORD $DOCKER_REPO
script:
- export CONFIG=$(echo $CONFIG1_STAGE | jq -c) && docker stack deploy --with-registry-auth -c ./docker/stage/app.yml app
Переопределяем переменную DOCKER_HOST для того, чтобы команда docker в Gitlab CI
взаимодействовала с удаленным сервером, который мы настроили в предыдущем параграфе.
Наш образ хранится в приватном репозитории, для доступа к которому используем docker login.
Чтобы наша команда docker stack deploy использовала полученную авторизации в репозитории,
указываем параметр --with-registry-auth.
yaml-файл конфигурации ./docker/stage/app.yml, имеет следующий вид:
version: '3.8'
services:
app:
image: ${DOCKER_REPO}/${DOCKER_IMAGE}
environment:
— CONFIG
ports:
— "9091:9091"
— "8444:8444"
depends_on:
— postgres
— redis
deploy:
replicas: 3
update_config:
parallelism: 2
delay: 3s
order: start-first
failure_action: rollback
monitor: 1m
restart_policy:
max_attempts: 3
# ... другие контейнеры
docker stack deploy использует переменные окружения для формирования
окончательного вида конфигурации. Поэтому в файле используются переменные
${DOCKER_REPO}, ${DOCKER_IMAGE} и CONFIG.
Вся структура deploy в yaml файле указывает на то, как выполняется деплой:
order: start-first отвечает за то, чтобы сначала запустился контейнер новой версии
контейнера, а затем уже остановился старый — та самая бесперебойность.parallelism: 2 определяет сколько пар контейнеров могут быть одновременно обновлены.
Чем больше данный параметр, тем больше будет нагрузка на сервер во время деплоя.monitor: 1m указывает сколько времени после создания контейнера docker-сервис
следит за его состоянием, чтобы понять, был ли деплой успешен.failure_action: rollback определяет что делать с деплоем в случае проблемы и
в данном случае выбран откат до предыдущей версии.