Поток пайплайна
Эта страница описывает полный жизненный цикл CI/CD-пайплайна Meduza — от git push до работающего сервиса на KVM-хосте.
Общая схема
flowchart TD
A[Разработчик пушит в ветку] --> B{Какая ветка?}
B -->|dev| C[Цель: dev]
B -->|stage| D[Цель: stage]
B -->|main| E[Цель: prod]
C --> F[Этап сборки]
D --> F
E --> F
F --> G[docker build с --platform linux/amd64]
G --> H[Тегирование образа commit SHA]
H --> I[Тегирование образа именем окружения]
I --> J[Отправка в gitlab.amzgit.com:5050]
J --> K[Этап деплоя]
K --> L[Установка Nomad CLI на alpine-раннере]
L --> M[SSH на KVM-хост]
M --> N[SCP job.nomad.hcl + var-файл]
N --> O["nomad job run -var image_tag=SHA"]
O --> P[Сервис работает с новым образом]
style A fill:#4a6fa5,stroke:#2d4a7a,color:#fff
style P fill:#4a9a5c,stroke:#2d7a3a,color:#fff
style F fill:#c9a24e,stroke:#a68232,color:#fff
style K fill:#c9a24e,stroke:#a68232,color:#fffЭтап 1: Сборка
Этап сборки запускается при каждом пуше в dev, stage или main. Каждый сервис в репозитории получает собственную параллельную задачу сборки.
Что происходит
- Раннер запускает контейнер
docker:24с Docker-in-Docker (docker:24-dind) в качестве вспомогательного сервиса. - Авторизация в реестре с помощью учётных данных GitLab:bash
docker login gitlab.amzgit.com:5050 -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD - Переход в каталог сервиса (
$SERVICE_DIR). - Сборка образа с фиксацией платформы
linux/amd64:bashdocker build ${BUILD_ARGS} \ --platform linux/amd64 \ -t gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4 . - Отправка тега commit SHA в реестр.
- Присвоение и отправка тега окружения (
dev,stageилиprod) в зависимости от ветки.
Параллельные сборки
Когда репозиторий содержит несколько сервисов (например, Hub включает backend и frontend), задачи сборки выполняются параллельно:
gantt
title Выполнение этапа сборки
dateFormat X
axisFormat %s
section Сборка
build:backend :0, 90
build:frontend :0, 70
section Деплой
deploy (ожидает все сборки) :90, 30Этап деплоя не начинается, пока все задачи сборки не завершатся успешно. Если любая сборка падает, пайплайн останавливается.
Ошибки сборки
Неудачная сборка полностью блокирует деплой. Типичные причины сбоев:
- Синтаксические ошибки в
Dockerfile - Отсутствующие зависимости сборки
BUILD_ARGSссылаются на неопределённые ARG в Dockerfile- Сетевые проблемы при загрузке базовых образов
Проверьте логи CI-задачи, чтобы увидеть конкретную ошибку docker build.
Этап 2: Деплой
После успешного завершения всех сборок запускается задача деплоя для соответствующего окружения.
Что происходит
- Запускается alpine-раннер (
alpine:3.19) — минимальный образ для запуска CLI-инструментов. - Устанавливается Nomad CLI в раннер.
- Настраивается SSH с использованием секретов из CI/CD-переменных GitLab (приватный ключ для KVM-хоста).
- Файлы передаются по SCP на KVM-хост:
job.nomad.hcl— спецификация Nomad-задачи- Файл переменных для окружения (например,
vars/dev.vars,vars/prod.vars)
- Nomad-задача отправляется на KVM-хосте:bash
nomad job run \ -var image_tag=${CI_COMMIT_SHORT_SHA} \ -var-file=vars/${ENV_NAME}.vars \ job.nomad.hcl - Nomad загружает новый образ из реестра и заменяет работающую аллокацию.
Диаграмма последовательности деплоя
sequenceDiagram
participant GL as GitLab Runner
participant KVM as KVM Host
participant NM as Nomad
participant REG as Container Registry
GL->>GL: Install Nomad CLI
GL->>KVM: SCP job.nomad.hcl + var-file
GL->>KVM: SSH nomad job run -var image_tag=a1b2c3d4
KVM->>NM: Submit job specification
NM->>NM: Schedule allocation
NM->>REG: Pull image a1b2c3d4
REG-->>NM: Image layers
NM->>NM: Start container
NM-->>KVM: Allocation running
KVM-->>GL: Exit 0 (success)Соответствие веток и окружений
Весь пайплайн управляется тем, в какую ветку выполнен пуш:
| Ветка | Теги сборки | Цель деплоя | Nomad Var-файл |
|---|---|---|---|
dev | $SHA + dev | dev-окружение | vars/dev.vars |
stage | $SHA + stage | stage-окружение | vars/stage.vars |
main | $SHA + prod | prod-окружение | vars/prod.vars |
Feature-ветки
Пуши в ветки, отличные от dev, stage или main, не запускают никаких задач пайплайна. Чтобы протестировать feature-ветку в CI, сначала влейте её в dev.
Полный пример пайплайна
Вот как выглядит полный пайплайн для сервиса Hub при пуше в ветку dev:
# Triggered by: git push origin dev
# Job 1: build:backend
# - extends: .docker_build
# - Builds back/Dockerfile
# - Pushes: gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4
# - Pushes: gitlab.amzgit.com:5050/meduza/hub/backend:dev
# Job 2: build:frontend (runs in parallel with Job 1)
# - extends: .docker_build
# - Builds front/Dockerfile with --build-arg VITE_API_URL=...
# - Pushes: gitlab.amzgit.com:5050/meduza/hub/frontend:a1b2c3d4
# - Pushes: gitlab.amzgit.com:5050/meduza/hub/frontend:dev
# Job 3: deploy:dev (runs after Jobs 1 & 2 succeed)
# - extends: .nomad_deploy
# - SSHes into KVM host
# - Runs: nomad job run -var image_tag=a1b2c3d4 -var-file=vars/dev.vars job.nomad.hclВременная шкала
flowchart LR
A["git push origin dev"] --> B["build:backend<br/>(~90 сек)"]
A --> C["build:frontend<br/>(~70 сек)"]
B --> D["deploy:dev<br/>(~30 сек)"]
C --> D
D --> E["Сервис доступен на dev"]
style A fill:#4a6fa5,stroke:#2d4a7a,color:#fff
style E fill:#4a9a5c,stroke:#2d7a3a,color:#fffТипичное общее время пайплайна: 2--3 минуты от пуша до работающего сервиса.
Решение проблем
Ошибки на этапе сборки
Образ не собирается
Проверьте вывод docker build в логах CI-задачи. Типичные причины:
- Базовый образ не найден (сетевая проблема или неверный тег)
COPYссылается на файлы, исключённые.dockerignore- Аргумент сборки требуется, но не передан через
BUILD_ARGS
Отправка в реестр не удалась
Убедитесь, что $CI_REGISTRY_USER и $CI_REGISTRY_PASSWORD установлены. Они автоматически предоставляются в GitLab CI, но могут не работать, если реестр проекта отключён. Перейдите в Settings > Packages and registries > Container Registry и подтвердите, что он включён.
Ошибки на этапе деплоя
SSH-соединение отклонено
KVM-хост может быть недоступен, или SSH-ключ мог быть обновлён. Проверьте CI/CD-переменные с SSH-ключом и убедитесь, что хост работает.
Отправка Nomad-задачи не удалась
Типичные причины:
- Некорректный HCL-синтаксис в
job.nomad.hcl - В var-файле отсутствует обязательная переменная
- Nomad-сервер не запущен на KVM-хосте
Подключитесь к KVM-хосту по SSH вручную и выполните:
nomad job validate job.nomad.hcl
nomad job plan -var image_tag=test -var-file=vars/dev.vars job.nomad.hclОшибки загрузки образа во время выполнения
Если Nomad принял задачу, но аллокация упала, наиболее вероятная причина — ошибка загрузки образа. Проверьте:
- Тег образа существует в реестре
- KVM-хост может достучаться до
gitlab.amzgit.com:5050 - Docker-учётные данные на KVM-хосте не истекли
# On the KVM host:
docker pull gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4