Обзор задачи
В статье рассматриваются различные варианты настройки CI/CD с использованием GitLab CI/CD и werf.
Конечный pipeline состоит из следующего набора стадий:
build-and-publish
— стадия сборки и публикации образов приложения;deploy
— стадия деплоя приложения для одного из контуров кластера;dismiss
— стадия удаления приложения для review окружения;cleanup
— стадия очистки хранилища стадий и Docker registry.
Набор контуров (а равно — окружений GitLab) в кластере Kubernetes может варьироваться в зависимости от многих факторов. В статье будут приведены различные варианты организации окружений для следующих:
Далее последовательно рассматриваются стадии pipeline и различные варианты их организации. Изложение построено от общего к частному. В конце статьи приведены окончательные версии .gitlab-ci.yml
для готовых workflow.
Независимо от workflow, все версии конфигурации подчиняются следующим правилам:
- Сборка и публикация выполняется при каждом push в репозитории.
- Выкат/удаление review окружений:
- Выкат на review окружение возможен только в рамках Merge Request (MR).
- Review окружения удаляются с помощью инструментария GitHub (по кнопке в разделе Environment), автоматически при удалении ветки или отсутствии активности в MR в течение суток.
- Очистка запускается один раз в день по расписанию на master.
Для выкатов review окружения и staging и production окружений предложены самые популярные варианты по организации. Каждый вариант для staging и production окружений сопровождается всевозможными способами отката релиза в production.
С общей информацией по организации CI/CD с помощью werf, а также информацией по конструированию своего workflow, можно ознакомиться в общей статье
Требования
- Кластер Kubernetes и настроенный для работы с ним
kubectl
. - GitLab-сервер версии выше 10.x либо учетная запись на gitlab.com.
- Docker registry, встроенный в GitLab или выделенный.
- Приложение, которое успешно собирается и деплоится с werf.
- Понимание основных концептов GitLab CI/CD.
Инфраструктура
- Кластер Kubernetes.
- GitLab со встроенным Docker registry.
- Узел или группа узлов, с предустановленным werf и зависимостями.
Организовать работу werf внутри Docker-контейнера можно, но мы не поддерживаем данный способ. Найти информацию по этому вопросу и обсудить можно в issue. В данном примере и в целом мы рекомендуем использовать shell executor.
Процесс деплоя требует наличия доступа к кластеру через kubectl
, поэтому необходимо установить и настроить kubectl
на узле, с которого будет запускаться werf.
Если не указывать конкретный контекст опцией --kube-context
или переменной окружения WERF_KUBE_CONTEXT
, то werf будет использовать контекст kubectl
по умолчанию.
В конечном счете werf требует наличия доступа на используемых узлах:
- к Git-репозиторию кода приложения;
- к Docker registry;
- к кластеру Kubernetes.
Настройка runner
На узле, где предполагается запуск werf, установим и настроим GitLab-runner:
- Создадим проект в GitLab и добавим push кода приложения.
- Получим токен регистрации GitLab-runner’а:
- заходим в проекте в GitLab
Settings
—>CI/CD
; - во вкладке
Runners
необходимый токен находится в секцииSetup a specific Runner manually
.
- заходим в проекте в GitLab
- Установим GitLab-runner по инструкции.
- Зарегистрируем
gitlab-runner
, выполнив шаги за исключением следующих моментов:- используем
werf
в качестве тега runner’а; - используем
shell
в качестве executor для runner’а.
- используем
-
Добавим пользователя
gitlab-runner
в группуdocker
.sudo usermod -aG docker gitlab-runner
- Установим Docker и настроим
kubectl
, если они не были установлены ранее. - Установим зависимости werf.
-
Установим multiwerf пользователем
gitlab-runner
:# переключение пользователя sudo su gitlab-runner # добавление ~/bin в PATH export PATH=$PATH:$HOME/bin echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc # установка multiwerf в директорию ~/bin mkdir -p ~/bin cd ~/bin curl -L https://raw.githubusercontent.com/werf/multiwerf/master/get.sh | bash
- Скопируем файл конфигурации
kubectl
в домашнюю папку пользователяgitlab-runner
.mkdir -p /home/gitlab-runner/.kube && sudo cp -i /etc/kubernetes/admin.conf /home/gitlab-runner/.kube/config && sudo chown -R gitlab-runner:gitlab-runner /home/gitlab-runner/.kube
После того, как GitLab-runner настроен, можно переходить к настройке pipeline.
Сборка и публикация образов приложения
Build and Publish:
stage: build-and-publish
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf build-and-publish
except: [schedules]
tags: [werf]
Забегая вперед, очистка хранилища стадий и Docker registry предполагает запуск соответствующего задания по расписанию.
Так как при очистке не требуется выполнять сборку образов, то указываем except: [schedules]
, чтобы стадия сборки не запускалась в случае работы pipeline по расписанию.
Конфигурация задания достаточно проста, поэтому хочется сделать акцент на том, чего в ней нет — явной авторизации в Docker registry, вызова docker login
.
В простейшем случае, при использовании встроенного Docker registry, авторизация выполняется автоматически при вызове команды werf ci-env
. В качестве необходимых аргументов используются переменные окружения GitLab CI_JOB_TOKEN
(подробнее про модель разграничения доступа при выполнении заданий в GitLab можно прочитать здесь) и CI_REGISTRY_IMAGE
.
При вызове werf ci-env
создаётся временный docker config, который используется всеми командами в shell-сессии (в том числе docker). Таким образов, параллельные задания никак не пересекаются при использовании docker и временный токен в конфигурации не перетирается.
Если необходимо выполнить авторизацию с произвольными учётными данными, docker login
должен выполняться после вызова werf ci-env
(подробнее про авторизацию в отдельной статье).
Выкат приложения
Прежде всего необходимо описать шаблон, общую часть для деплоя в любой контур, что позволит уменьшить размер файла .gitlab-ci.yml
, улучшит его читаемость, а также позволит далее сосредоточиться на workflow.
.base_deploy: &base_deploy
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
dependencies:
- Build and Publish
except: [schedules]
tags: [werf]
При использовании шаблона base_deploy
для каждого контура будет определяться своё окружение GitLab:
Example:
<<: *base_deploy
environment:
name: <environment name>
url: <url>
...
...
При выполнении задания, werf ci-env
устанавливает переменную WERF_ENV
в соответствии с именем окружения GitLab (CI_ENVIRONMENT_SLUG
).
Для того, чтобы по-разному конфигурировать приложение для используемых контуров кластера в helm-шаблонах можно использовать Go-шаблоны и переменную .Values.global.env
, что соответствует значению опции --env
или переменной окружения WERF_ENV
.
Также в шаблоне используется адрес окружения, URL для доступа к разворачиваемому в контуре приложению, который передаётся параметром global.env_url
.
Это значение может использоваться в helm-шаблонах, например, для конфигурации Ingress-ресурсов.
Далее будут представлены популярные стратегии и практики, на базе которых мы предлагаем выстраивать ваши процессы в GitLab.
Варианты организации review окружения
Как уже было сказано ранее, review окружение — это временный контур, поэтому помимо выката, у этого окружения также должна быть и очистка.
Рассмотрим базовые конфигурации Review
и Stop Review
заданий, которые лягут в основу всех предложенных вариантов.
Review:
<<: *base_deploy
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}-${CI_MERGE_REQUEST_ID}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
only: [merge_requests]
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
В задание Review
описывается выкат review-релиза в динамическое окружение, в основу имени которого закладывается уникальный идентификатор MR. Параметр auto_stop_in
позволяет указать период отсутствия активности в MR, после которого окружение GitLab будет автоматически остановлено. Остановка окружения GitLab сама по себе никак не влияет на ресурсы в кластере, review-релиз, поэтому в дополнении необходимо определить задание, которое вызывается при остановке (on_stop
). В нашем случае, это задание Stop Review
.
Задание Stop Review
выполняет удаление review-релиза, а также остановку окружения GitLab (action: stop
): werf удаляет helm-релиз и namespace в Kubernetes со всем его содержимым (werf dismiss). Задание Stop Review
может быть запущено вручную после деплоя на review контур, а также автоматически GitLab-сервером, например, при удалении соответствующей ветки в результате слияния ветки с master и указания соответствующей опции в интерфейсе GitLab.
Для выполнения werf dismiss
требуется werf.yaml, так как в нём содержаться шаблоны имени релиза и namespace. При удалении ветки нет возможности использовать исходники из git, поэтому в задании Stop Review
используется werf.yaml, сохранённый при выполнении задания Review
, и отключено подтягивание изменений из git (GIT_STRATEGY: none
).
Таким образом, по умолчанию закладываем следующие варианты удаления review окружения:
- вручную;
- автоматически при отсутствии активности MR в течение суток и при удалении ветки.
Далее разберём основные стратегии при организации выката review окружения.
Мы не ограничиваем вас предложенными вариантами, даже напротив — рекомендуем комбинировать их и создавать конфигурацию workflow под нужды вашей команды
№1 Вручную
Данный вариант реализует подход описанный в разделе Выкат на review из pull request по кнопке
При таком подходе пользователь выкатывает и удаляет окружение по кнопке в pipeline.
Он самый простой и может быть удобен в случае, когда выкаты происходят редко и review окружение не используется при разработке. По сути, для проверки перед принятием MR.
Review:
<<: *base_deploy
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}-${CI_MERGE_REQUEST_ID}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
only: [merge_requests]
when: manual
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
№2 Автоматически по имени ветки
Данный вариант реализует подход описанный в разделе Выкат на review из ветки по шаблону автоматически
В предложенном ниже варианте автоматический релиз выполняется для каждого коммита в MR, в случае, если имя git-ветки имеет префикс review-
.
Review:
<<: *base_deploy
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}-${CI_MERGE_REQUEST_ID}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
rules:
- if: $CI_MERGE_REQUEST_ID && $CI_COMMIT_REF_NAME =~ /^review-/
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
№3 Полуавтоматический режим с лейблом (рекомендованный)
Данный вариант реализует подход описанный в разделе Выкат на review из pull request автоматически после ручной активации
Полуавтоматический режим с лейблом — это комплексное решение, объединяющие первые два варианта.
При проставлении специального лейбла, в примере ниже review
, пользователь активирует автоматический выкат в review окружения для каждого коммита.
При снятии лейбла происходит остановка окружения GitLab, удаление review-релиза.
Review:
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- >
# do optional deploy/dismiss
if [ -z "$PRIVATE_TOKEN" ]; then
echo "\$PRIVATE_TOKEN is not defined" >&2
exit 1
fi
api_url=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}
if ! response_body=$(curl -sS --header "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" ${api_url}); then
echo "GET ${api_url}"
echo ${response_body}
exit 1
fi
if ! echo ${response_body} | jq .labels[] >/dev/null 2>&1; then
echo "GET ${api_url}"
echo ${response_body}
exit 1
fi
if echo ${response_body} | jq .labels[] | grep -q '^"review"$'; then
werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
else
if werf helm get $(werf helm get-release) 2>/dev/null; then
werf dismiss --with-namespace
fi
fi
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}-${CI_MERGE_REQUEST_ID}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
dependencies:
- Build and Publish
only: [merge_requests]
tags: [werf]
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
Для проверки наличия лейбла у MR используется GitLab API.
Так как токена CI_JOB_TOKEN
недостаточно для работы с private репозиториями, необходимо сгенерировать специальный токен PRIVATE_TOKEN
.
Варианты организации staging и production окружений
Предложенные далее варианты являются наиболее эффективными комбинациями правил выката staging и production окружений.
В нашем случае, данные окружения являются определяющими, поэтому названия вариантов соответствуют названиям окончательных готовых workflow, предложенных в конце статьи.
№1 Fast and Furious (рекомендованный)
Данный вариант реализует подходы описанные в разделах Выкат на production из master автоматически и Выкат на production-like из pull request по кнопке
Выкат в production происходит автоматически при любых изменениях в master. Выполнить выкат в staging можно по кнопке в MR.
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [merge_requests]
when: manual
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [master]
Варианты отката изменений в production:
- revert изменений в master (рекомендованный);
- выкат стабильного MR или воспользовавшись кнопкой Rollback.
№2 Push the Button
Данный вариант реализует подходы описанные в разделах Выкат на production из master по кнопке и Выкат на staging из master автоматически
Выкат production осуществляется по кнопке у коммита в master, а выкат в staging происходит автоматически при любых изменениях в master.
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [master]
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [master]
when: manual
Варианты отката изменений в production:
- по кнопке у стабильного коммита или воспользовавшись кнопкой Rollback (рекомендованный);
- выкат стабильного MR и нажатии кнопки.
№3 Tag everything (рекомендованный)
Данный вариант реализует подходы описанные в разделах Выкат на production из тега автоматически и Выкат на staging из master по кнопке
Выкат в production выполняется при проставлении тега, а в staging по кнопке у коммита в master.
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [master]
when: manual
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only:
- tags
Варианты отката изменений в production:
- нажатие кнопки на другом теге (рекомендованный);
- создание нового тега на старый коммит (так делать не надо).
№4 Branch, branch, branch!
Данный вариант реализует подходы описанные в разделах Выкат на production из ветки автоматически и Выкат на production-like из ветки автоматически
Выкат в production происходит автоматически при любых изменениях в ветке production, а в staging при любых изменениях в ветке master.
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [master]
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [production]
Варианты отката изменений в production:
- воспользовавшись кнопкой Rollback;
- revert изменений в ветке production;
- revert изменений в master и fast-forward merge в ветку production;
- удаление коммита из ветки production и push-force.
Очистка образов
Cleanup:
stage: cleanup
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
- werf cleanup
only: [schedules]
tags: [werf]
В werf встроен эффективный механизм очистки, который позволяет избежать переполнения Docker registry и диска сборочного узла от устаревших и неиспользуемых образов. Более подробно ознакомиться с функционалом очистки, встроенным в werf, можно здесь.
Чтобы использовать очистку, необходимо создать Personal Access Token
в GitLab с необходимыми правами. С помощью данного токена будет осуществляться авторизация в Docker registry перед очисткой.
Для вашего тестового проекта вы можете просто создать Personal Access Token
а вашей учетной записи GitLab. Для этого откройте страницу Settings
в GitLab (настройки вашего профиля), затем откройте раздел Access Token
. Укажите имя токена, в разделе Scope отметьте api
и нажмите Create personal access token
— вы получите Personal Access Token
.
Чтобы передать Personal Access Token
в переменную окружения GitLab откройте ваш проект, затем откройте Settings
—> CI/CD
и разверните Variables
. Создайте новую переменную окружения WERF_IMAGES_CLEANUP_PASSWORD
и в качестве ее значения укажите содержимое Personal Access Token
. Для безопасности отметьте созданную переменную как protected
.
Стадия очистки запускается только по расписанию, которое вы можете определить открыв раздел CI/CD
—> Schedules
настроек проекта в GitLab. Нажмите кнопку New schedule
, заполните описание задания и определите шаблон запуска в обычном cron-формате. В качестве ветки оставьте master (название ветки не влияет на процесс очистки), отметьте Active
и сохраните pipeline.
Полный .gitlab-ci.yml для готовых workflow
Детали workflow
Подробнее про workflow можно почитать в отдельной статье
- Сборка и публикация.
- Выкат на review контур по стратегии №3 Полуавтоматический режим с лейблом (рекомендованный).
- Выкат на staging и production контуры осуществляется по стратегии №1 Fast and Furious (рекомендованный).
- Очистка стадий выполняется по расписанию раз в сутки.
.gitlab-ci.yml
stages:
- build-and-publish
- deploy
- dismiss
- cleanup
Build and Publish:
stage: build-and-publish
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf build-and-publish
except: [schedules]
tags: [werf]
.base_deploy: &base_deploy
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
dependencies:
- Build and Publish
tags: [werf]
Review:
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- >
# do optional deploy/dismiss
if [ -z "$PRIVATE_TOKEN" ]; then
echo "\$PRIVATE_TOKEN is not defined" >&2
exit 1
fi
api_url=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}
if ! response_body=$(curl -sS --header "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" ${api_url}); then
echo "GET ${api_url}"
echo ${response_body}
exit 1
fi
if ! echo ${response_body} | jq .labels[] >/dev/null 2>&1; then
echo "GET ${api_url}"
echo ${response_body}
exit 1
fi
if echo ${response_body} | jq .labels[] | grep -q '^"review"$'; then
werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
else
if werf helm get $(werf helm get-release) 2>/dev/null; then
werf dismiss --with-namespace
fi
fi
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}-${CI_MERGE_REQUEST_ID}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
dependencies:
- Build and Publish
only: [merge_requests]
tags: [werf]
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [merge_requests]
when: manual
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [master]
Cleanup:
stage: cleanup
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
- werf cleanup
only: [schedules]
tags: [werf]
Детали workflow
Подробнее про workflow можно почитать в отдельной статье
- Сборка и публикация.
- Выкат на review контур по стратегии №1 Вручную.
- Выкат на staging и production контуры осуществляется по стратегии №2 Push the Button.
- Очистка стадий выполняется по расписанию раз в сутки.
.gitlab-ci.yml
stages:
- build-and-publish
- deploy
- dismiss
- cleanup
Build and Publish:
stage: build-and-publish
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf build-and-publish
except: [schedules]
tags: [werf]
.base_deploy: &base_deploy
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
dependencies:
- Build and Publish
except: [schedules]
tags: [werf]
Review:
<<: *base_deploy
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}-${CI_MERGE_REQUEST_ID}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
only: [merge_requests]
when: manual
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [master]
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [master]
when: manual
Cleanup:
stage: cleanup
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
- werf cleanup
only: [schedules]
tags: [werf]
Детали workflow
Подробнее про workflow можно почитать в отдельной статье
- Сборка и публикация.
- Выкат на review контур по стратегии №1 Вручную.
- Выкат на staging и production контуры осуществляется по стратегии №3 Tag everything.
- Очистка стадий выполняется по расписанию раз в сутки.
.gitlab-ci.yml
stages:
- build-and-publish
- deploy
- dismiss
- cleanup
Build and Publish:
stage: build-and-publish
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf build-and-publish
except: [schedules]
tags: [werf]
.base_deploy: &base_deploy
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
dependencies:
- Build and Publish
except: [schedules]
tags: [werf]
Review:
<<: *base_deploy
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
only: [merge_requests]
when: manual
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [master]
when: manual
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [tags]
Cleanup:
stage: cleanup
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
- werf cleanup
only: [schedules]
tags: [werf]
Детали workflow
Подробнее про workflow можно почитать в отдельной статье
- Сборка и публикация.
- Выкат на review контур по стратегии №2 Автоматически по имени ветки.
- Выкат на staging и production контуры осуществляется по стратегии №4 Branch, branch, branch!.
- Очистка стадий выполняется по расписанию раз в сутки.
.gitlab-ci.yml
stages:
- build-and-publish
- deploy
- dismiss
- cleanup
Build and Publish:
stage: build-and-publish
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf build-and-publish
except: [schedules]
tags: [werf]
.base_deploy: &base_deploy
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf deploy --set "global.env_url=$(echo ${CI_ENVIRONMENT_URL} | cut -d / -f 3)"
dependencies:
- Build and Publish
except: [schedules]
tags: [werf]
Review:
<<: *base_deploy
environment:
name: review-${CI_MERGE_REQUEST_ID}
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
on_stop: Stop Review
auto_stop_in: 1 day
artifacts:
paths:
- werf.yaml
rules:
- if: $CI_MERGE_REQUEST_ID && $CI_COMMIT_REF_NAME =~ /^review-/
Stop Review:
stage: dismiss
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf dismiss --with-namespace
environment:
name: review-${CI_MERGE_REQUEST_ID}
action: stop
variables:
GIT_STRATEGY: none
dependencies:
- Review
only: [merge_requests]
when: manual
tags: [werf]
Deploy to Staging:
<<: *base_deploy
environment:
name: staging
url: http://${CI_PROJECT_NAME}.kube.DOMAIN
only: [master]
Deploy to Production:
<<: *base_deploy
environment:
name: production
url: https://www.company.org
only: [production]
Cleanup:
stage: cleanup
script:
- type multiwerf && . $(multiwerf use 1.1 stable --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
- werf cleanup
only: [schedules]
tags: [werf]