Как выглядит логика работы хорошего CI/CD пайплайна?

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

Ответ

В наших проектах мы строим CI/CD пайплайны, которые обеспечивают быструю и безопасную доставку кода. Вот логика типичного пайплайна для микросервиса на Python, развернутого в Kubernetes.

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

# .gitlab-ci.yml
stages:
  - lint
  - test
  - build
  - deploy-staging
  - deploy-prod

variables:
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

# 1. Линтинг и проверка кода
lint:
  stage: lint
  image: python:3.10-slim
  script:
    - pip install black flake8 mypy
    - black --check --diff .
    - flake8 .
    - mypy --ignore-missing-imports src/

# 2. Запуск тестов
test:
  stage: test
  image: python:3.10-slim
  services:
    - postgres:13-alpine
  variables:
    POSTGRES_DB: test_db
  script:
    - pip install -r requirements.txt
    - pytest tests/ --cov=src --cov-report=xml -v
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml

# 3. Сборка Docker-образа
build:
  stage: build
  image: docker:20.10
  services:
    - docker:20.10-dind
  script:
    - docker build -t $DOCKER_IMAGE .
    - docker push $DOCKER_IMAGE

# 4. Деплой на staging-окружение
deploy-staging:
  stage: deploy-staging
  image: bitnami/kubectl:latest
  script:
    - kubectl config use-context staging-cluster
    - kubectl set image deployment/myapp-api api=$DOCKER_IMAGE -n staging
  environment:
    name: staging
  only:
    - merge_requests  # Деплой для каждого MR

# 5. Деплой на production (требует ручного подтверждения)
deploy-prod:
  stage: deploy-prod
  image: bitnami/kubectl:latest
  script:
    - kubectl config use-context prod-cluster
    # Используем стратегию blue-green для минимального даунтайма
    - kubectl apply -f k8s/manifests/production-blue-green.yaml
    - kubectl rollout status deployment/myapp-api-prod-green
  environment:
    name: production
  only:
    - main  # Только для мёржа в main
  when: manual  # Ручной запуск

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

  • Изоляция: Каждый этап выполняется в своём контейнере. Зависимости тестов не влияют на сборку.
  • Быстрота обратной связи: Этапы lint и test выполняются первыми и быстро, чтобы разработчик узнал о проблемах как можно раньше.
  • Идемпотентность и воспроизводимость: Сборка всегда из одного и того же коммита (CI_COMMIT_SHA).
  • Безопасность: Доступ к production-кластеру ограничен, деплой требует manual approval. Секреты хранятся в vault (например, HashiCorp Vault) или protected variables CI.
  • Мониторинг: После деплоя автоматически запускаются smoke-тесты, а метрики (латентность, ошибки) отслеживаются в Grafana. При падении метрик может автоматически запускаться откат (rollback).