Какие executors (исполнители) вы использовали в GitLab CI/CD и в каких сценариях?

Ответ

В GitLab Runner можно настроить разные executors, и выбор зависит от требований к изоляции, скорости и среде выполнения. Я работал со следующими:

1. Docker (Наиболее часто используемый): Запускает каждую джобу в отдельном контейнере. Идеален для воспроизводимости и чистоты окружения.

  • Сценарий: Сборка и тестирование приложений на разных версиях Node.js/Python/Go.
  • Пример .gitlab-ci.yml:

    build:
      stage: build
      image: golang:1.21-alpine
      script:
        - go build -o myapp ./cmd/app
      artifacts:
        paths:
          - myapp
    
    test:
      stage: test
      image: golang:1.21-alpine
      services:
        - postgres:15-alpine # Запуск сервиса-контейнера (БД) рядом с джобой
      variables:
        POSTGRES_DB: test_db
      script:
        - go test -v ./...

2. Kubernetes: Запускает каждую джобу как Pod в Kubernetes-кластере. Обеспечивает наилучшую масштабируемость и интеграцию с инфраструктурой.

  • Сценарий: В средах, где вся инфраструктура работает на k8s. Позволяет запрашивать специфичные ресурсы (CPU/RAM) и использовать ServiceAccounts для доступа к кластеру.
  • Конфигурация Runner (config.toml):
    concurrent = 10
    [[runners]]
      name = "k8s-runner"
      url = "https://gitlab.example.com"
      token = "__TOKEN__"
      executor = "kubernetes"
      [runners.kubernetes]
        namespace = "gitlab-runner"
        image = "alpine:latest"
        cpu_limit = "1"
        memory_limit = "1Gi"

3. Shell: Выполняет команды напрямую на хосте, где установлен Runner. Самый быстрый, но без изоляции.

  • Сценарий: Развертывание (deployment) на том же сервере, где работает Runner (например, для простых стендов). Или для задач, требующих прямого доступа к хосту (обновление самого Runner'а).
  • Важно: Требует тщательного контроля безопасности и чистки окружения между джобами.

4. Docker Machine + Docker (Auto-scaling): Использовал в облачных средах для автоматического создания виртуальных машин под нагрузкой. Runner создает временные инстансы в AWS EC2 или GCP Compute Engine, запускает на них джобы в Docker, а затем уничтожает инстансы. Отлично подходит для экономии ресурсов при непостоянной нагрузке.

Выбор executor'а — это всегда компромисс между скоростью, безопасностью, воспроизводимостью и стоимостью. Для большинства проектов Docker executor является оптимальным по умолчанию.

Ответ 18+ 🔞

А, ну это же про тех, кто у нас джобы запускает, эти самые раннеры! Я с ними, блядь, накоротке, как с родными. Тут главное — не охуеть от выбора, а то их, сука, как собак нерезаных. Расскажу, с какими воевал.

1. Docker (Этот, блядь, вездесущий): Каждую задачу в свой личный контейнер засовывает. Чистота — пиздец, воспроизводимость — огонь. Как будто каждый раз на свежий, только что протёртый стол садишься.

  • Куда лезет: Когда надо собрать или потестить твой код на разных версиях Node.js, Python или Go. Один раз настроил образ — и потом хоть обосрись, всё одинаково работает.
  • Вот, смотри, как в конфиге выглядит:

    build:
      stage: build
      image: golang:1.21-alpine
      script:
        - go build -o myapp ./cmd/app
      artifacts:
        paths:
          - myapp
    
    test:
      stage: test
      image: golang:1.21-alpine
      services:
        - postgres:15-alpine # Поднимает базу рядом, как соседку-алкашку
      variables:
        POSTGRES_DB: test_db
      script:
        - go test -v ./...

2. Kubernetes: Это уже, ёпта, тяжёлая артиллерия. Каждая джоба у тебя как отдельный Pod в кластере летает. Масштабируется так, что мама не горюй, но и возни с ним — овердохуища.

  • Куда лезет: Когда у тебя вся инфраструктура уже на кубересах живёт. Тут можно выкручиваться: просить конкретно сколько оперативки, ядер, доступ к секретам через ServiceAccount — полная власть, но и ответственность, блядь, соответствующая.
  • Как его, падлу, настраивают (config.toml):
    concurrent = 10
    [[runners]]
      name = "k8s-runner"
      url = "https://gitlab.example.com"
      token = "__TOKEN__"
      executor = "kubernetes"
      [runners.kubernetes]
        namespace = "gitlab-runner"
        image = "alpine:latest"
        cpu_limit = "1"
        memory_limit = "1Gi"

3. Shell: А вот это, блядь, дикий запад. Команды выполняются прямо на голом хосте, где сам раннер сидит. Скорость — хуй в пальто, мгновенная, потому что никаких контейнеров. Но изоляции — нихуя. Один скрипт может нагадить так, что следующий в этом дерьме захлебнётся.

  • Куда лезет: Ну, например, когда деплоишь на тот же сервер, где и раннер. Или для каких-то системных задач, где надо к железу напрямую. Но тут, чувак, доверия ебать ноль — нужно следить, чтобы между запусками всё подчищалось, а то будет тебе хиросима.

4. Docker Machine + Docker (Автомасштабирование): Это вообще песня! Раннер, когда работы дохуя, сам лезет в облако (AWS, GCP), создаёт там виртуальную машину, на ней джобу в докере запускает, а потом эту машину — бац! — и удаляет. Экономия, блядь, конкретная, если пуши не идут 24/7. Красиво, но иногда с настройкой этой автоматизации можно так охуеть, что волосы дыбом встанут.

Короче, выбор-то всегда, сука, как на рынке: хочешь быстро и дёшево — рискуешь безопасностью, хочешь надёжно и изолированно — платишь скоростью и сложностью. Для большинства проектов, если не знаешь с чего начать — бери Docker executor и не парься. Он как швейцарский нож: и колбасу порежет, и бутылку откроет.