Skip to content

Поток пайплайна

Эта страница описывает полный жизненный цикл CI/CD-пайплайна Meduza — от git push до работающего сервиса на KVM-хосте.

Общая схема

mermaid
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. Каждый сервис в репозитории получает собственную параллельную задачу сборки.

Что происходит

  1. Раннер запускает контейнер docker:24 с Docker-in-Docker (docker:24-dind) в качестве вспомогательного сервиса.
  2. Авторизация в реестре с помощью учётных данных GitLab:
    bash
    docker login gitlab.amzgit.com:5050 -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
  3. Переход в каталог сервиса ($SERVICE_DIR).
  4. Сборка образа с фиксацией платформы linux/amd64:
    bash
    docker build ${BUILD_ARGS} \
      --platform linux/amd64 \
      -t gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4 .
  5. Отправка тега commit SHA в реестр.
  6. Присвоение и отправка тега окружения (dev, stage или prod) в зависимости от ветки.

Параллельные сборки

Когда репозиторий содержит несколько сервисов (например, Hub включает backend и frontend), задачи сборки выполняются параллельно:

mermaid
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: Деплой

После успешного завершения всех сборок запускается задача деплоя для соответствующего окружения.

Что происходит

  1. Запускается alpine-раннер (alpine:3.19) — минимальный образ для запуска CLI-инструментов.
  2. Устанавливается Nomad CLI в раннер.
  3. Настраивается SSH с использованием секретов из CI/CD-переменных GitLab (приватный ключ для KVM-хоста).
  4. Файлы передаются по SCP на KVM-хост:
    • job.nomad.hcl — спецификация Nomad-задачи
    • Файл переменных для окружения (например, vars/dev.vars, vars/prod.vars)
  5. Nomad-задача отправляется на KVM-хосте:
    bash
    nomad job run \
      -var image_tag=${CI_COMMIT_SHORT_SHA} \
      -var-file=vars/${ENV_NAME}.vars \
      job.nomad.hcl
  6. Nomad загружает новый образ из реестра и заменяет работающую аллокацию.

Диаграмма последовательности деплоя

mermaid
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 + devdev-окружениеvars/dev.vars
stage$SHA + stagestage-окружениеvars/stage.vars
main$SHA + prodprod-окружениеvars/prod.vars

Feature-ветки

Пуши в ветки, отличные от dev, stage или main, не запускают никаких задач пайплайна. Чтобы протестировать feature-ветку в CI, сначала влейте её в dev.

Полный пример пайплайна

Вот как выглядит полный пайплайн для сервиса Hub при пуше в ветку dev:

yaml
# 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

Временная шкала

mermaid
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 вручную и выполните:

bash
nomad job validate job.nomad.hcl
nomad job plan -var image_tag=test -var-file=vars/dev.vars job.nomad.hcl

Ошибки загрузки образа во время выполнения

Если Nomad принял задачу, но аллокация упала, наиболее вероятная причина — ошибка загрузки образа. Проверьте:

  1. Тег образа существует в реестре
  2. KVM-хост может достучаться до gitlab.amzgit.com:5050
  3. Docker-учётные данные на KVM-хосте не истекли
bash
# On the KVM host:
docker pull gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4

Документация по инфраструктуре