Полный гайд по GitLab Runner (от shell до production-grade CI/CD)
Авторский стиль: понятный, прямой, без воды. Подходит как справочник и как учебник «с нуля до продакшна». — Владыка
Содержание
- Введение — что такое GitLab Runner и зачем он нужен
- Архитектура: GitLab ↔ Runner
- Установка GitLab Runner — базовая (Ubuntu)
- Первый runner: Shell executor — минимально и просто
- Docker executor — почему он круче shell
- DIND vs Docker socket — что выбрать
- Kubernetes executor — масштабирование и облако
- Docker Machine / Autoscaling runners
- Регистрация runner: параметры, теги, scopes
- Параметры конфигурации
config.toml— что важно - Параллельность, concurrency, limit jobs
- Кэширование и артефакты: ускоряем сборки
- Секреты: GitLab CI variables, Vault, и best practices
- CI/CD паттерны: миграции, канареечный/blue-green деплой, rollback
- Интеграция: Helm, ArgoCD, Docker Registry
- Безопасность и hardening Runner'ов
- Мониторинг, логирование и алёрты для Runner'ов
- Troubleshooting: частые проблемы и решения
- Чек-лист перед продакшен-деплоем
- Примеры `.gitlab-ci.yml` и полезные команды
- FAQ
- Ресурсы и ссылки
1. Введение — что такое GitLab Runner и зачем он нужен
GitLab Runner — агент, который выполняет job’ы из GitLab CI pipelines. GitLab хранит дефиницию pipeline в .gitlab-ci.yml, Runner — тот, кто реально запускает шаги: билдит, тестит, деплоит.
- Runner получает job от GitLab
- Выполняет его в выбранном executor’е (shell, docker, kubernetes...)
- Возвращает статус и артефакты в GitLab

2. Архитектура: GitLab ↔ Runner
# Схема (представление)
GitLab (server) GitLab Runner (agent)
├─ executor: shell
├─ executor: docker (+ dind / socket)
└─ executor: kubernetes (pods)
Runner использует registration token, может быть shared или specific (привязан к проекту/группе).
3. Установка GitLab Runner — базовая (Ubuntu)
# Установка через deb-пакет
curl -L --output /tmp/gitlab-runner.deb "https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_amd64.deb"
sudo dpkg -i /tmp/gitlab-runner.deb
# Включить сервис
sudo systemctl enable --now gitlab-runner
# Проверить версию
gitlab-runner --version
4. Первый runner: Shell executor — минимально и просто
Когда использовать: локальная разработка, простые задачи. Минусы: нет изоляции — risk to host.
Регистрация shell-runner (CLI)
sudo gitlab-runner register \
--non-interactive \
--url "https://gitlab.com/" \
--registration-token "TOKEN_FROM_UI" \
--executor "shell" \
--description "shell-runner-01" \
--tag-list "shell,local" \
--run-untagged="true" \
--locked="false"
Простой .gitlab-ci.yml для shell
stages:
- build
- test
build:
stage: build
script:
- echo "building on $(uname -a)"
- make build
tags:
- shell
test:
stage: test
script:
- make test
tags:
- shell
Рекомендация: не использовать shell-runner для untrusted code в продакшене.
5. Docker executor — почему он круче shell
- Изоляция: каждый job в контейнере
- Репродуцируемость: явные образы
- Чистота хоста
Подготовка
sudo apt-get install -y docker.io
sudo usermod -aG docker gitlab-runner
sudo systemctl restart gitlab-runner
Регистрация Docker runner
sudo gitlab-runner register \
--url "https://gitlab.com/" \
--registration-token "TOKEN" \
--executor "docker" \
--description "docker-runner-01" \
--docker-image "docker:24.0.0" \
--tag-list "docker,linux" \
--run-untagged="true"
Пример pipeline (docker build + push)
image: docker:24.0.0
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
stages:
- build
build:
stage: build
script:
- docker info
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
only:
- main
6. DIND vs Docker socket — что выбрать
- DIND (docker-in-docker): запуск docker daemon внутри контейнера (service docker:dind). Плюс — изоляция job’ов. Минус — сложнее TLS и конфигурация.
- Docker socket (/var/run/docker.sock): монтируем сокет хоста. Плюс — быстро и просто. Минус — security risk (container получает доступ к хосту).
Пример mount socket (config.toml):
[[runners]]
executor = "docker"
[runners.docker]
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
7. Kubernetes executor — масштабирование и облако
Runner создаёт Pod для каждого job — идеален для масштабирования и изоляции в кластере.
Установка через Helm
helm repo add gitlab https://charts.gitlab.io
helm upgrade --install gitlab-runner gitlab/gitlab-runner \
--namespace gitlab-runner --create-namespace \
--set runnerRegistrationToken="" \
--set rbac.create=true \
--set runners.privileged=true
Совет: создавай отдельный namespace и минимальные RBAC-права для runner'ов.
8. Docker Machine / Autoscaling runners
Опции для динамического масштабирования runner'ов:
- docker-machine — runner создаёт VMs под нагрузку (облака: AWS, DO и т.д.).
- k8s autoscaling — использовать Cluster Autoscaler / HPA чаще предпочтительней.
# пример (фрагмент config.toml)
[[runners]]
executor = "docker+machine"
[runners.machine]
MachineDriver = "amazonec2"
MachineOptions = ["amazonec2-region=us-east-1", "amazonec2-ami=ami-..."]
9. Регистрация runner: параметры, теги, scopes
- description — имя runner;
- tags — фильтрация job'ов (docker, k8s, windows);
- run-untagged — запускать job'ы без тегов;
- locked — закрепить runner за проектом/группой.
Теги — ключ к разделению ответственности: назначай runner'ы по тегам и целям.
10. Параметры конфигурации config.toml — что важно
concurrent = 4
[[runners]]
name = "docker-runner-01"
url = "https://gitlab.com/"
token = "..."
executor = "docker"
[runners.cache]
Type = "s3"
Path = "runner-cache"
Shared = true
[runners.docker]
tls_verify = false
image = "docker:24.0.0"
privileged = true
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
Ключевые опции: concurrent (глобальный), runners[].limit (для runner), privileged (для DIND).
11. Параллельность, concurrency, limit jobs
concurrent— сколько job'ов одновременно обрабатывает процесс runner;runners[].limit— предел на конкретный runner;parallelв job — запускает N параллельных копий одного job.
12. Кэширование и артефакты: ускоряем сборки
Артефакты
build:
stage: build
script:
- make build
artifacts:
paths:
- build/
expire_in: 1 week
Кэш
cache:
paths:
- vendor/
- node_modules/
Совет: используйте ключи кэша (например, по lock-файлам) и общие backend'ы (S3/Minio) для шаринга между runner'ами.
13. Секреты: GitLab CI variables, Vault, и best practices
- GitLab variables — удобны, помечайте protected & masked.
- Vault — централизованная ротация, audit и RBAC.
- Kubernetes Secrets / ExternalSecrets — runtime-injection в кластер.
Пример: Vault в pipeline
deploy:
stage: deploy
image: hashicorp/vault:latest
script:
- vault login $VAULT_TOKEN
- export DB_PASS=$(vault kv get -field=password secret/prod/mysql)
- # использовать DB_PASS
only:
- main
Не храните секреты в репозиториях и не логируйте их; используйте masked/protected переменные и Vault Agent/Injector там, где это нужно.
14. CI/CD паттерны: миграции, канареечный/blue-green деплой, rollback
Миграции — общие принципы
- Запускать миграции отдельно, перед заменой приложения
- Делать миграции idempotent
- Иметь backup/dump перед критическими миграциями
migrate:
stage: migrate
image: flyway/flyway:latest
script:
- flyway -url="$DB_JDBC" -user="$DB_USER" -password="$DB_PASS" migrate
when: manual
Blue-Green (упрощённо)
# deploy green
kubectl apply -f deployment-app-green.yaml
# smoke tests...
# switch service selector
kubectl patch svc app -p '{"spec":{"selector":{"version":"green"}}}'
Canary (через Argo Rollouts — предпочтительно)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: example
spec:
replicas: 4
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 1m }
- setWeight: 50
- pause: { duration: 1m }
template:
spec:
containers:
- name: example
image: registry.example/example:TAG
15. Интеграция: Helm, ArgoCD, Docker Registry
Docker Registry
Используйте immutable tags (semver + commit sha). GitLab Registry — удобный вариант, но можно внешний.
Helm
helm create myapp
helm upgrade --install myapp ./chart --namespace prod --set image.tag=$CI_COMMIT_SHORT_SHA
ArgoCD
CI обновляет Git (values или helm chart), ArgoCD синхронизирует кластер — классический GitOps-поток.
16. Безопасность и hardening Runner'ов
- Не используйте shell executor для untrusted pipeline'ов.
- Минимизируйте права (least privilege) для service accounts.
- Не монтируйте /var/run/docker.sock в публичных раннерах без контроля.
- Храните registration token в защищённом месте.
- Используйте protected & masked variables в GitLab.
17. Мониторинг, логирование и алёрты для Runner'ов
- Метрики: queue length, time per job, failed jobs
- Инструменты: Prometheus + Grafana, ELK/Loki
- Alerting: high queue length, offline runners
18. Troubleshooting: частые проблемы и решения
- Job в статусе
pending - Проверь, онлайн ли runner, совпадают ли теги job и runner.
- Docker build — permission denied
- Проверь права на сокет, user inside container, mount volumes.
- Cannot connect to docker daemon
- Если DIND — проверь сервис docker:dind и переменные TLS. Если socket — проверь mount.
- Runner не регистрируется
- Проверь registration token и URL GitLab.
19. Чек-лист перед продакшен-деплоем
- Runner'ы на отдельной инфраструктуре (не dev ноуты)
- Secrets — в Vault / External Secrets; не в git
- Protected & masked variables в GitLab
- Backup перед миграциями
- Liveness & readiness probes (k8s)
- Мониторинг и alerting настроены
- Rollback план и runbook
20. Примеры и полезные команды
Шаблон для PHP app (build → migrate → deploy via Helm)
stages:
- build
- migrate
- deploy
variables:
IMAGE_TAG: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
HELM_RELEASE: "myapp"
KUBE_NAMESPACE: "prod"
before_script:
- echo $CI_JOB_TOKEN | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY
build:
stage: build
script:
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
tags:
- docker
migrate:
stage: migrate
image: flyway/flyway:latest
script:
- export DB_PASS=$(vault kv get -field=password secret/prod/mysql)
- flyway -url="jdbc:mysql://$DB_HOST:3306/$DB_NAME" -user="$DB_USER" -password="$DB_PASS" migrate
when: manual
dependencies: []
deploy:
stage: deploy
image: alpine/helm:3.14.0
script:
- helm upgrade --install $HELM_RELEASE charts/myapp --namespace $KUBE_NAMESPACE --set image.tag=$CI_COMMIT_SHORT_SHA
only:
- main
Команды управления runner
# Check version
gitlab-runner --version
# Control service
sudo systemctl status gitlab-runner
sudo systemctl start gitlab-runner
# Register runner
sudo gitlab-runner register
# Uninstall runner
sudo gitlab-runner uninstall
21. FAQ
- Нужен ли свой runner или хватит shared?
- Для приватных/критичных проектов — свой runner. Shared удобен для open source и быстрых тестов.
- Как безопасно хранить Docker credentials?
- GitLab CI variables (protected/masked) или Vault. Не храните в коде.
- Как ускорить pipeline?
- Кэшируйте зависимости, используйте slim образы, параллелизм и persistent runners c warm cache.
22. Ресурсы и ссылки
Заключение
GitLab Runner гибкий и мощный. Начинай с shell для простоты, переходи на docker для изоляции, а для production — kubernetes + ArgoCD + Vault. Следи за безопасностью: не монтируй docker.sock в публичных раннерах и отделяй среду CI от платформы продакшена.