Как доставлять билд в окружение?

«Как доставлять билд в окружение?» — вопрос из категории CI/CD, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В моих проектах доставка билда — это полностью автоматизированный этап CI/CD пайплайна. Я предпочитаю подход, основанный на артефактах и декларативных деплоях.

Стандартный пайплайн (на примере GitLab CI):

  1. Сборка и создание артефакта: Приложение упаковывается в Docker-образ.

    # .gitlab-ci.yml (stage: build)
    build:
      stage: build
      script:
        - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
        - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
      artifacts:
        reports:
          dotenv: build.env # Сохраняем переменную с тегом образа
  2. Промоутинг артефакта: Образ с тегом $CI_COMMIT_SHA помещается в container registry (GitLab Registry, Harbor, ECR). Для продвижения между стадиями (dev -> stage -> prod) я либо перетегирую образ (например, :staging), либо использую артефакт в виде переменной, указывающей на конкретный хэш.

  3. Деплой в целевое окружение: Использую инструменты инфраструктуры как код (IaC).

    • Для Kubernetes: Обновляю манифест Helm или kustomize, подставляя новый тег образа, и применяю через kubectl или ArgoCD.
      # values.yaml для Helm
      image:
        repository: $CI_REGISTRY_IMAGE
        tag: $CI_COMMIT_SHA
    • Для виртуальных машин (реже): Использую Ansible playbook, который скачивает собранный артефакт (например, JAR-файл из Nexus) и перезапускает сервис.

Ключевые принципы, которых я придерживаюсь:

  • Идемпотентность: Деплой одним и тем же артефактом всегда приводит к одинаковому результату.
  • Версионирование: Каждый билд имеет уникальный идентификатор (хэш коммита, семантическая версия).
  • Откат: Возможность быстро откатиться к предыдущей версии артефакта (например, развернув образ с предыдущим тегом).
  • Валидация: Перед деплоем на prod запускаются автоматические тесты в staging-окружении.