📨 CI/CD¶
CI/CD — практика автоматизации проверки, сборки и доставки изменений из Git в окружения.
Status: In progress
1. Continuous Integration
CI (Continuous Integration) — частая интеграция изменений в общую ветку с автоматической сборкой и тестами. Цель — рано ловить поломки, а не «собирать в пятницу руками».
Входы
- Код в Git (исходники, тесты)
- Зависимости —
requirements.txt,package.json,go.mod,pom.xml… - Конфиг пайплайна —
.gitlab-ci.yml,Jenkinsfile, GitHub Actions workflow,Dockerfile
Этапы
Типичный CI-пайплайн:
- Checkout — клон репозитория / PR
- Install — зависимости
- Lint / static analysis — стиль, типы, секреты
- Test — unit / integration
- Build — бинарь, образ, пакет
- Publish — артефакт в registry / artifact store
Артефакты
Результат CI — то, что дальше забирает CD (или человек):
| Артефакт | Пример |
|---|---|
| Контейнерный образ | myapp:1.2.3 в registry |
| Бинарь / пакет | .jar, Go binary, .deb |
| Архив | dist.tar.gz |
| Отчёты тестов | JUnit XML, coverage |
| Сгенерированные конфиги | манифесты для деплоя |
Artifacts (в GitLab) — файлы job’а, которые сохраняются и передаются между stages.
Cache — ускорение (например node_modules/); это не «выход» пайплайна и не замена artifacts.
2. Delivery и Deployment
После успешного CI артефакт нужно доставить в окружения. Здесь путают два термина.
Continuous Delivery vs Continuous Deployment
| Continuous Delivery | Continuous Deployment | |
|---|---|---|
| До прод | Автоматически до staging (или «готово к релизу») | Автоматически и в production |
| В прод | Нужен ручной approve / кнопка | Без ручного шага (после зелёного пайплайна) |
| Смысл | Всегда есть релиз, готовый к выкату | Каждый зелёный коммит может уйти в прод |
Оба опираются на один и тот же CI; отличается только политика выката в prod.
Окружения
Частая лестница:
- DEV — быстрый деплой для разработчиков
- STAGING — близко к прод, финальные проверки
-
PROD — пользователи
Инструменты деплоя: Docker / Compose, Kubernetes, Ansible, Terraform — см. разделы Docker, IaC, Ansible.
3. Типы тестов в pipeline
| Тип | Что проверяет | Где в CI |
|---|---|---|
| Unit | Функции / классы изолированно | почти всегда, быстро |
| Integration | Связка модулей, API, БД | после unit |
| Functional | Соответствие сценариям/требованиям | mid |
| UI | Интерфейс (Selenium и др.) | медленнее, отдельно |
| Load | Поведение под нагрузкой | не на каждый commit |
| Security | Уязвимости, секреты, SAST/DAST | по политике |
| Resilience | Сбои сети/БД, деградация | периодически |
| Compatibility | ОС / браузеры / версии | по матрице |
Чем левее и быстрее — тем чаще в каждом pipeline; тяжёлые тесты — по расписанию или на release-ветке.
4. Pipeline на практике
От push до деплоя — одна цепочка (инструмент может быть любой: GitLab, GitHub Actions, Jenkins…):
- Push / PR — изменения в Git
- Триггер CI — сервер видит commit и стартует job’ы
- Сборка — зависимости + build
- Тесты — unit → integration (по пайплайну)
- Качество — lint, coverage, security scan
- Артефакт — образ/бинарь в registry
- Уведомление — зелёный/красный статус в MR
- Deploy — auto на DEV/staging; в prod — auto или manual
- Мониторинг — проверка после выката
5. GitLab CI
GitLab Runner выполняет job’ы из .gitlab-ci.yml: сборка, тесты, деплой.
Executor — способ запуска команд (Shell, Docker, Kubernetes, SSH…). На практике чаще всего Docker.
Пример stages: build → test → deploy
stages:
- build
- test
- deploy
build:
stage: build
script:
- echo "Building..."
- make build
artifacts:
paths:
- dist/
test:
stage: test
script:
- make test
deploy:
stage: deploy
script:
- ./deploy.sh
rules:
- if: $CI_COMMIT_BRANCH == "main"
Runner и executors
| Executor | Как работает |
|---|---|
| Shell | Команды на хосте Runner |
| Docker | Новый контейнер на каждый job |
| Kubernetes | Pod в кластере |
| SSH | Удалённая машина по SSH |
| VirtualBox / Docker Machine | VM / облачные ноды (реже) |
Типы Runner по привязке:
- Shared — общий на инстанс / группу проектов
- Specific — только выбранный проект или группа
Установка Runner
Пакет (Debian/Ubuntu):
curl -L --output /tmp/gitlab-runner.deb \
https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_amd64.deb
sudo dpkg -i /tmp/gitlab-runner.deb
sudo gitlab-runner register
Docker:
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
Регистрация интерактивно:
docker run --rm -it \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
gitlab/gitlab-runner register
Укажите URL GitLab, registration token, executor (docker) и default image (например docker:stable).
6. Docker в CI: DooD, DinD, Sysbox
Чтобы в job’е собирать и пушить образы, Runner’у нужен доступ к Docker. Три распространённых подхода.
DooD (Docker-outside-of-Docker)
Job-контейнер монтирует сокет хоста /var/run/docker.sock.
- Плюс: просто, быстро
- Минус: job’ы делят Docker-демон хоста (изоляция слабее)
В config.toml у Runner:
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
DinD (Docker-in-Docker)
Рядом с job поднимается сервис docker:dind — отдельный Docker-демон.
- Плюс: изоляция от хоста лучше, чем DooD
- Минус: нужен
privileged = true(или аналог) — выше риск
В config.toml:
privileged = true
В job обычно DOCKER_TLS_CERTDIR: "" и services: [docker:dind].
Sysbox
Альтернатива привилегированному DinD: runtime sysbox-runc даёт rootless-подобную изоляцию контейнеров с «настоящим» Docker внутри.
В config.toml:
runtime = "sysbox-runc"
Имеет смысл, когда DooD слишком «общий», а privileged DinD не проходит security-политику.
Пример .gitlab-ci.yml
Три job’а на разных Runner tags (dood-tag, dind-tag, sysbox-tag):
stages:
- DooD
- dind
- Sysbox
DooD_Job:
stage: DooD
script:
- docker images
tags:
- dood-tag
dind_Job:
stage: dind
variables:
DOCKER_TLS_CERTDIR: ""
services:
- docker:dind
script:
- docker images
tags:
- dind-tag
Sysbox_Job:
stage: Sysbox
variables:
DOCKER_TLS_CERTDIR: ""
script:
- docker images
tags:
- sysbox-tag
Вопросы
В разработке..