Как работает процесс автоматизации с использованием GitLab CI/CD?

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

Ответ

В моих проектах GitLab CI/CD — это единая платформа для автоматизации сборки, тестирования и развертывания приложений. Конфигурация описывается в файле .gitlab-ci.yml в корне репозитория, что позволяет хранить пайплайн как код.

Базовый рабочий процесс:

  1. Разработчик делает push в репозиторий GitLab.
  2. GitLab Runner (агент) подхватывает задание (job) из пайплайна.
  3. Runner создает изолированное окружение (чаще всего Docker-контейнер), выполняет скрипты и возвращает результат.
  4. GitLab отображает статус пайплайна в интерфейсе Merge Request.

Пример .gitlab-ci.yml для развертывания микросервиса на Kubernetes:

# Определяем стадии пайплайна по порядку
stages:
  - test
  - build
  - security-scan
  - deploy-staging
  - deploy-production

# Переменные, доступные во всех заданиях
variables:
  DOCKER_IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  KUBE_NAMESPACE: myapp

# Кеширование зависимостей для ускорения сборок
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/
    - .gradle/caches

# 1. Стадия тестирования
test-unit:
  stage: test
  image: node:18-alpine
  script:
    - npm ci
    - npm run test:unit
  artifacts:
    reports:
      junit: reports/junit.xml  # GitLab соберет и отобразит отчет о тестах

# 2. Стадия сборки Docker-образа
build-docker:
  stage: build
  image: docker:24
  services:
    - docker:24-dind  # Docker-in-Docker для сборки внутри контейнера
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $DOCKER_IMAGE_TAG .
    - docker push $DOCKER_IMAGE_TAG
  only:
    - merge_requests  # Запускать только для MR и main ветки
    - main

# 3. Статический анализ безопасности кода (SAST)
sast:
  stage: security-scan
  image: registry.gitlab.com/gitlab-org/security-products/analyzers/bandit:latest
  script:
    - /analyzer run
  artifacts:
    reports:
      sast: gl-sast-report.json  # Результаты появятся в UI в разделе Security

# 4. Развертывание в staging-окружение
deploy-staging:
  stage: deploy-staging
  image: bitnami/kubectl:latest
  script:
    - echo "Deploying to staging..."
    - kubectl config use-context staging-cluster
    - sed "s|__IMAGE_TAG__|$DOCKER_IMAGE_TAG|g" k8s/deployment.yaml | kubectl apply -f - -n $KUBE_NAMESPACE
    - kubectl rollout status deployment/myapp -n $KUBE_NAMESPACE --timeout=120s
  environment:
    name: staging
    url: https://staging.myapp.example.com  # Ссылка будет в UI окружения
  only:
    - main  # Автоматически деплоить в staging при мерже в main

# 5. Ручное развертывание в production
deploy-production:
  stage: deploy-production
  image: bitnami/kubectl:latest
  script:
    - echo "Deploying to production..."
    - kubectl config use-context production-cluster
    - sed "s|__IMAGE_TAG__|$DOCKER_IMAGE_TAG|g" k8s/deployment.yaml | kubectl apply -f - -n $KUBE_NAMESPACE
    - kubectl rollout status deployment/myapp -n $KUBE_NAMESPACE --timeout=180s
  environment:
    name: production
    url: https://myapp.example.com
  when: manual  # Требует ручного нажатия кнопки в UI для запуска
  only:
    - main

Ключевые возможности для DevOps:

  • Динамические окружения: Для каждой feature-ветки можно автоматически создавать изолированное окружение для тестирования.
  • Артефакты: Результаты одной стадии (например, собранный JAR-файл) можно передать на следующую.
  • Распределенные Runners: Можно настроить разные раннеры для разных задач (например, мощные машины для сборки, раннеры внутри кластера K8s для деплоя).
  • Интеграция с Kubernetes: Прямое подключение кластеров через gitlab-agent (KAS) для безопасного деплоя и мониторинга.
  • Auto DevOps: Для стандартных проектов можно использовать предопределенный пайплайн, который автоматически определяет язык, собирает, тестирует и деплоит.
  • Правила (rules): Гибкая логика запуска заданий.
    deploy-to-review:
      script: ...
      rules:
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"  # Только для MR
          variables:
            ENVIRONMENT: "review/$CI_MERGE_REQUEST_ID"
        - if: $CI_COMMIT_BRANCH == "main"                   # Или для main ветки

Такой подход позволяет реализовать надежный пайплайн от коммита до продакшена с контролем качества, безопасностью и возможностью ручного утверждения.