GitLab-Runner Guide

17 October 2025

Полный гайд по GitLab Runner (от shell до production-grade CI/CD)

Авторский стиль: понятный, прямой, без воды. Подходит как справочник и как учебник «с нуля до продакшна». — Владыка


Содержание

  1. Введение — что такое GitLab Runner и зачем он нужен
  2. Архитектура: GitLab ↔ Runner
  3. Установка GitLab Runner — базовая (Ubuntu)
  4. Первый runner: Shell executor — минимально и просто
  5. Docker executor — почему он круче shell
  6. DIND vs Docker socket — что выбрать
  7. Kubernetes executor — масштабирование и облако
  8. Docker Machine / Autoscaling runners
  9. Регистрация runner: параметры, теги, scopes
  10. Параметры конфигурации config.toml — что важно
  11. Параллельность, concurrency, limit jobs
  12. Кэширование и артефакты: ускоряем сборки
  13. Секреты: GitLab CI variables, Vault, и best practices
  14. CI/CD паттерны: миграции, канареечный/blue-green деплой, rollback
  15. Интеграция: Helm, ArgoCD, Docker Registry
  16. Безопасность и hardening Runner'ов
  17. Мониторинг, логирование и алёрты для Runner'ов
  18. Troubleshooting: частые проблемы и решения
  19. Чек-лист перед продакшен-деплоем
  20. Примеры `.gitlab-ci.yml` и полезные команды
  21. FAQ
  22. Ресурсы и ссылки

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.


Заключение

GitLab Runner гибкий и мощный. Начинай с shell для простоты, переходи на docker для изоляции, а для production — kubernetes + ArgoCD + Vault. Следи за безопасностью: не монтируй docker.sock в публичных раннерах и отделяй среду CI от платформы продакшена.

Leave a comment

Popular Posts

Advertisement

Headlines