Перейти к содержанию

📨 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-пайплайн:

  1. Checkout — клон репозитория / PR
  2. Install — зависимости
  3. Lint / static analysis — стиль, типы, секреты
  4. Test — unit / integration
  5. Build — бинарь, образ, пакет
  6. 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.

Окружения

Частая лестница:

  1. DEV — быстрый деплой для разработчиков
  2. STAGING — близко к прод, финальные проверки
  3. 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…):

  1. Push / PR — изменения в Git
  2. Триггер CI — сервер видит commit и стартует job’ы
  3. Сборка — зависимости + build
  4. Тесты — unit → integration (по пайплайну)
  5. Качество — lint, coverage, security scan
  6. Артефакт — образ/бинарь в registry
  7. Уведомление — зелёный/красный статус в MR
  8. Deploy — auto на DEV/staging; в prod — auto или manual
  9. Мониторинг — проверка после выката
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
Вопросы

В разработке..