CD проекта, как реализовать?
Всем привет, никогда не настраивал выкладку своего проекта автоматически, поэтому прошу помочь с организацией всего этого.
Имеется проект, в стиле микро сервисной архитектуры с использованием docker-compose, все хранится на GitLab, репозитории имеют следующий вид:
- ServiceA - сервис A, хранит в себе исходный код +
Dockerfile - ServiceB - сервис B, хранит в себе исходный код +
Dockerfile - ServiceC - сервис C, хранит в себе исходный код +
Dockerfile - Application - Перечисляет в себе сервисы (ServiceA...C), посредством
git submodules+docker-compose.yml;
В docker-compose декларированы все сервисы из репозиториев (Помимо своих "модулей", перечислен docker-сервис из готового образа) и поэтому для запуска приложения достаточно, просто выполнить docker-compose up -d --build
Существуют 2 среды:
- Staging - среда-приемки, тестовая, нет доступа по ssh
- Production - прод, есть доступ по ssh (лучше конечно не трогать ssh)
Хочется сделать следующие:
- Когда я обновляю
master- ветку, репозиторияApplication, обновление автоматически доставляется на Staging-среду и приложение обновляется. - Когда все было успешно протестировано на Staging-среде, можно было нажать на
кнопочку(Подтвердить выкладку) и изменения доставлялись на Production-среду (Процесс аналогичному на Staging-среде).
Теперь собственно сам вопрос :)
Каким образом можно организовать данный процесс? Возможно по неопытности, я пропустил какие-то процессы, но которые должны быть.
Ответы (1 шт):
Имеется проект, в стиле микро сервисной архитектуры с использованием docker-compose, все хранится на GitLab, репозитории имеют следующий вид:
Service A - сервис A, хранит в себе исходный код +
Dockerfile
Во-первых, желательно, чтобы микросервиcы можно было деплоить отдельно.
В текущем описании конфигурация только в Application stack, а это не гибко.
Если Service A меняется, нужно менять Application.
Решение:
- своё описание инфраструктуры
docker-compose.*.yml(в том числе иdocker-compose.development.yml, пользуемсяdocker-compose.override.yml, делая ссылку) - описание
environmentdocker-compose file (прямо в репозитории сервиса) - свои тесты, build & push в docker registry или через
Application(.gitlab-ci.yml) - уменьшаем связность сервисов
- коммуникация через external network
нет доступа по ssh
есть доступ по ssh (лучше конечно не трогать ssh)
SSH вполне себе вариант для деплоя. Главное не руками через ssh.
Application stack
Описываем в .gitlab-ci.yml qa, integration tests, деплои как staging / production. Тут же можно положить скрипты для автоматизации деплоя.
Разберем на примере.
Некий аналог Application моей реализации CD. Смотри services/example (аналог Service A)
Для автоматизации используется bash + ansible.
Ansible:
- Конфигурации серверов по
environmentи секреты (минимально шифруемhost_vars.yml) - деплой через ssh (передаем файл stack, после удаляем)
Bash:
- Проверки services, environments
- Merge docker-compose.*.yml в один стек (build / deploy)
Как выглядит:
./build example staging
Билдим сервис example и заливаем в registry. Помним, что в этот момент нужны sources.
Аналогично деплой.
./deploy example staging
Под капотом у нас ansible и ему скармливаем пароль от vault для secrets.
Можно использовать как group_vars, так и host_vars.
docker-compose.yml приводим к одному виду с ansible vars и уже через ansible контролируем переменные (кроме development).
Пример c gitlab
image: afsmnghr/ansible-gitlab-runner:1.2.1
variables:
...
stages:
- integration
- production
.ssh: &ssh |
eval "$(ssh-agent -s)"
echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
mkdir -p ~/.ssh
ssh-keyscan "$PROD_IP" >> ~/.ssh/known_hosts
.ansible: &ansible |
# WARNING: Ansible refuses to read from a world-writeable folder
chmod -v 600 "$(pwd)"
echo "$ANSIBLE_VAULT_PASSWORD" > .vault
build:
stage: integration
before_script:
- *ssh
- *ansible
script:
- ./build example production
after_script:
- rm -f .vault
only:
- tags
except:
refs:
- schedules
- branches
- develop
deploy:
stage: production
before_script:
- *ssh
- *ansible
script:
- ./deploy example production
after_script:
- rm -f .vault
only:
- tags
except:
refs:
- schedules
- branches
- develop
Пушим тег в master (настраиваем политики). Начинает билд и деплой на прод. Все легко реализовать, если базовые вещи можно описать простыми командами.
Вместо заключения
Основные проблемы и что может помочь:
- Автоматизация (ansible playbooks / roles)
- Secret management (ansible vault, hashicorp vault)
- Infra / servers inventory (ansible)
- IaC на каждый environment (много docker-compose файлов)