Ответ
В GitLab CI выполнение джобов на разных раннерах контролируется с помощью тегов (tags). Каждому GitLab Runner при регистрации присваиваются теги, описывающие его окружение (например, docker, kubernetes, aws, arm). В конфигурации пайплайна мы указываем, какой тег требуется для конкретной задачи.
Пример .gitlab-ci.yml:
stages:
- build
- test
- security-scan
- deploy
# Этап сборки выполняется на раннере с Docker, чтобы использовать Docker-in-Docker
build:
stage: build
tags:
- docker
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# Этап тестов запускаем в Kubernetes-кластере для масштабирования
run-unit-tests:
stage: test
tags:
- kubernetes
script:
- echo "Running tests in a dynamically provisioned pod..."
- ./run_tests.sh
# Сканирование безопасности выполняем на специальном раннере с предустановленными сканерами
sast-scan:
stage: security-scan
tags:
- security
script:
- trivy fs --severity HIGH,CRITICAL .
# Деплой в продовое окружение AWS выполняем на раннере с настроенным AWS CLI и правами
deploy-to-prod:
stage: deploy
tags:
- aws
- production
script:
- aws eks update-kubeconfig --name prod-cluster
- kubectl set image deployment/my-app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n production
only:
- main
Ключевые моменты для надежной конфигурации:
- Идемпотентность: Каждый job должен быть спроектирован так, чтобы его можно было запустить на любом раннере с подходящим тегом, а не на какой-то конкретной машине.
- Кеширование и артефакты: Для передачи данных между стадиями, выполняемыми на разных раннерах, необходимо явно объявлять
cacheилиartifacts. Кеш может быть привязан к тегу раннера, а артефакты загружаются/скачиваются из GitLab. - Динамическое выделение: Использование раннеров с тегом
kubernetesпозволяет GitLab динамически создавать pod для выполнения job, что эффективно для эфемерных задач, таких как тесты.