Запуск GitLab Runner в Yandex Serverless Containers
Важно
Часть ресурсов, необходимых для прохождения практического руководства, доступны только в регионе Россия.
В этом практическом руководстве вы научитесь запускать GitLab Runner
Чтобы запустить GitLab Runner в Serverless Containers:
- Подготовьте облако к работе.
- Создайте GitLab Runner и получите токен.
- Создайте секрет.
- Создайте сервисные аккаунты.
- Создайте API-ключ сервисного аккаунта.
- Создайте контейнер.
- Настройте вебхук в GitLab.
Если созданные ресурсы вам больше не нужны, удалите их.
Принцип работы
GitLab отправляет вебхук в созданный контейнер после создания Job. В контейнере запускается GitLab Runner, который забирает задачу на исполнение и завершает работу после выполнения. Это позволяет избежать постоянных затрат на виртуальные машины Yandex Compute Cloud, оплачивая только фактическое время работы раннера.
Вы можете ознакомиться с исходным кодом в репозитории
-
Сервис принимает HTTP-запросы на порту
PORT
(по умолчанию8080
) и путиWEBHOOK_PATH
(по умолчанию/
). -
При необходимости сервис проверяет секрет в заголовке
X-Gitlab-Token
с помощью значения переменнойGITLAB_SECRET
. -
Обрабатываются только запросы с заголовком
X-Gitlab-Event: Job Hook
. -
Из тела запроса извлекается поле
build_status
. Если его значениеpending
, сервис запускает команду:gitlab-runner run-single \ --url CI_SERVER_URL \ --token RUNNER_TOKEN \ --wait-timeout WAIT_TIMEOUT \ --executor docker \ --docker-privileged \ --max-builds MAX_BUILDS
-
При запуске контейнера сервис дополнительно:
- Монтирует
cgroup v2
(если требуется). - Готовит каталоги
/run
и/var/lib/docker
. - Запускает встроенный
dockerd
и ждет его готовности (DOCKERD_READY_TIMEOUT
).
- Монтирует
В сервисе используются следующие переменные окружения:
Переменная | По умолчанию | Обязательно | Описание |
---|---|---|---|
RUNNER_TOKEN |
— | Да | Токен GitLab Runner (Project/Group/Instance). |
CI_SERVER_URL |
https://gitlab.com |
Нет | Адрес GitLab CI. |
PORT |
8080 |
Нет | HTTP-порт. |
WEBHOOK_PATH |
/ |
Нет | Путь эндпоинта вебхука. |
GITLAB_SECRET |
— | Нет | Секрет для проверки заголовка X-Gitlab-Token . |
WAIT_TIMEOUT |
10 |
Нет | Значение для gitlab-runner --wait-timeout (в секундах). |
MAX_BUILDS |
1 |
Нет | Значение для gitlab-runner --max-builds . |
DOCKERD_READY_TIMEOUT |
5s |
Нет | Время ожидания готовности dockerd (time.Duration ). |
Ограничения:
- В руководстве используется только Docker executor. Вы можете самостоятельно собрать контейнер с необходимыми зависимостями и использовать в нем Shell executor.
- Каждый запрос вебхука запускает отдельный, одноразовый (эфемерный) раннер. Состояние между такими раннерами не сохраняется.
- Задания должны иметь теги, соответствующие тегам раннера. Если у
job
в.gitlab-ci.yml
не указаны подходящие теги, раннер не возьмет задание. Используйте опциюRun untagged jobs
при создании раннера, чтобы он брал все задачи.
Подготовьте облако к работе
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVE
илиTRIAL_ACTIVE
. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость поддержки инфраструктуры входит:
- Плата за количество вызовов контейнера, вычислительные ресурсы, выделенные для выполнения приложения, и исходящий трафик (см. тарифы Serverless Containers).
- Плата за хранение секретов (см. тарифы Yandex Lockbox).
Создайте GitLab Runner и получите токен
- В GitLab
создайте и откройте проект. - На панели слева выберите
Settings → CI/CD. - Раскройте раздел Runners и нажмите Create project runner.
- В поле Tags укажите теги задач, которые должен обрабатывать этот раннер.
- Нажмите Create runner.
- В разделе Step 1 скопируйте аутентификационный токен раннера (runner authentication token) и сохраните его.
Создайте секрет
Создайте секрет Yandex Lockbox с аутентификационным токеном раннера.
-
В консоли управления
выберите каталог, в котором вы будете создавать инфраструктуру. -
В списке сервисов выберите Lockbox.
-
Нажмите Создать секрет.
-
В поле Имя укажите имя секрета
gitlab-runner-token
. -
В блоке Данные секрета:
-
Выберите тип секрета
Пользовательский
. -
Добавьте значение токена GitLab Runner:
- В поле Ключ укажите
gitlab_runner_token
. - В поле Значение укажите аутентификационный токен раннера, который вы получили ранее.
- В поле Ключ укажите
-
-
Нажмите Создать.
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>
. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name
или --folder-id
.
Чтобы создать секрет, выполните команду:
yc lockbox secret create \
--name gitlab-runner-token \
--payload '[{"key": "gitlab_runner_token", "text_value": "<токен_раннера>"}]'
Где:
--name
— имя секрета.--payload
— содержимое секрета в виде массива YAML или JSON.<токен_раннера>
— аутентификационный токен раннера, который вы получили ранее.
Результат:
id: e6qdur7h55vd********
folder_id: b1g681qpemb4********
created_at: "2025-09-16T06:04:12.604Z"
name: gitlab-runner-token
status: ACTIVE
current_version:
id: e6qbaf927irb********
secret_id: e6qdur7h55vd********
created_at: "2025-09-16T06:04:12.604Z"
status: ACTIVE
payload_entry_keys:
- gitlab_runner_token
Чтобы создать секрет, воспользуйтесь методом REST API create для ресурса Secret или вызовом gRPC API SecretService/Create.
Создайте сервисные аккаунты
Создайте два сервисных аккаунта:
-
gitlab-runner-lockbox-payload-viewer
с рольюlockbox.payloadViewer
для доступа к секрету Lockbox. -
gitlab-runner-caller
с рольюserverless-containers.containerInvoker
на каталог. Этот сервисный аккаунт будет выполнять две функции:- От его имени GitLab будет вызывать контейнер. API-ключ будет указан в заголовке
Authorization
. - Его идентификатор будет использоваться GitLab для постановки задачи раннеру на выполнение, чтобы вызов контейнера выполнялся асинхронно. Идентификатор будет передан при создании ревизии контейнера.
При необходимости вы можете разделить эти функции между двумя разными сервисными аккаунтами.
- От его имени GitLab будет вызывать контейнер. API-ключ будет указан в заголовке
-
В консоли управления
выберите сервис Identity and Access Management. -
Нажмите Создать сервисный аккаунт.
-
Укажите имя сервисного аккаунта
gitlab-runner-caller
. -
Нажмите
Добавить роль и выберите рольserverless-containers.containerInvoker
. -
Нажмите Создать.
-
Аналогичным способом создайте сервисный аккаунт
gitlab-runner-lockbox-payload-viewer
без назначения роли. -
Назначьте сервисному аккаунту
gitlab-runner-lockbox-payload-viewer
роль на секрет:- В консоли управления
выберите сервис Lockbox. - Выберите секрет
gitlab-runner-token
. - На панели слева выберите
Права доступа. - Нажмите Назначить роли.
- Найдите и выберите сервисный аккаунт
gitlab-runner-lockbox-payload-viewer
. - Нажмите
Добавить роль и выберите рольlockbox.payloadViewer
. - Нажмите Сохранить.
- В консоли управления
-
Создайте сервисные аккаунты:
yc iam service-account create --name gitlab-runner-lockbox-payload-viewer yc iam service-account create --name gitlab-runner-caller
Результат:
id: ajenprbpf1s3******** folder_id: b1g681qpemb4******** created_at: "2025-09-16T06:06:13.092790480Z" name: gitlab-runner-lockbox-payload-viewer id: ajetqjm00ji8******** folder_id: b1g681qpemb4******** created_at: "2025-09-16T06:06:15.661704808Z" name: gitlab-runner-caller
-
Назначьте роли сервисным аккаунтам:
yc lockbox secret add-access-binding \ --name gitlab-runner-token \ --role lockbox.payloadViewer \ --service-account-name gitlab-runner-lockbox-payload-viewer yc resource-manager folder add-access-binding \ --id <идентификатор_каталога> \ --role serverless-containers.containerInvoker \ --service-account-name gitlab-runner-caller
Где:
--name
— имя секрета.--id
— идентификатор каталога.--role
— назначаемая роль.--service-account-name
— имя сервисного аккаунта.
Результат:
...1s...done (4s) ...1s...done (2s) effective_deltas: - action: ADD access_binding: role_id: serverless-containers.containerInvoker subject: id: ajetqjm00ji8******** type: serviceAccount
Чтобы создать сервисный аккаунт, воспользуйтесь методом REST API create для ресурса ServiceAccount или вызовом gRPC API ServiceAccountService/Create.
Чтобы назначить сервисному аккаунту роль lockbox.payloadViewer
на секрет, воспользуйтесь методом REST API updateAccessBindings для ресурса Secret или вызовом gRPC API SecretService/UpdateAccessBindings.
Чтобы назначить сервисному аккаунту роль serverless-containers.containerInvoker
на каталог, воспользуйтесь методом REST API updateAccessBindings для ресурса Folder или вызовом gRPC API FolderService/UpdateAccessBindings.
Создайте API-ключ сервисного аккаунта
Создайте API-ключ для сервисного аккаунта, который будет использоваться при вызове контейнера. API-ключ понадобится для настройки вебхука в GitLab.
- В консоли управления
выберите сервис Identity and Access Management. - Выберите созданный ранее сервисный аккаунт
gitlab-runner-caller
. - На панели сверху нажмите
Создать новый ключ и выберите пункт Создать API-ключ. - В поле Область действия выберите область действия
yc.serverless.containers.invoke
. - Нажмите Создать.
-
Создайте API-ключ для сервисного аккаунта
gitlab-runner-caller
:yc iam api-key create \ --service-account-name gitlab-runner-caller \ --scopes yc.serverless.containers.invoke
Где:
--service-account-name
— имя сервисного аккаунта.--scopes
— область действия ключа.
Результат:
api_key: id: aje3oa26mt52******** service_account_id: ajetqjm00ji8******** created_at: "2025-09-16T06:08:47.018697312Z" scope: yc.serverless.containers.invoke scopes: - yc.serverless.containers.invoke secret: AQVNw8KEa3SiA8vlpXEhfl9k-uYT22Ws********
Чтобы создать API-ключ, воспользуйтесь методом REST API create для ресурса ApiKey или вызовом gRPC API ApiKeyService/Create.
Сохраните полученный секретный ключ — получить его повторно невозможно.
Создайте контейнер
Создайте контейнер и ревизию контейнера с Docker-образом для запуска GitLab Runner.
Примечание
В примере эфемерный диск монтируется по пути /mnt
и расширяет доступное пространство корневой файловой системы на время выполнения контейнера. Docker хранит данные в /var/lib/docker
— благодаря расширению корневой файловой системы это место становится доступным.
-
В консоли управления
в списке сервисов выберите сервис Serverless Containers. -
Нажмите Создать контейнер.
-
Укажите имя контейнера
serverless-gitlab-runner
. -
Нажмите Создать.
-
Перейдите на вкладку Редактор.
-
В блоке Ресурсы укажите нужный объем RAM, например
1024 МБ
. -
В блоке Параметры образа:
-
Нажмите Укажите ссылку и в поле URL образа укажите
cr.yandex/yc/serverless/gitlab-runner
. -
В поле Переменные окружения добавьте переменные:
CI_SERVER_URL
—https://gitlab.com
.WEBHOOK_PATH
—/webhook
.
-
В поле Секреты Lockbox укажите:
- Переменная окружения —
RUNNER_TOKEN
. - Идентификатор секрета —
gitlab-runner-token
. - Идентификатор версии — идентификатор текущей версии.
- Ключ секрета —
gitlab_runner_token
.
- Переменная окружения —
-
-
В блоке Настройки:
- В поле Сервисный аккаунт укажите
gitlab-runner-lockbox-payload-viewer
. - В поле Таймаут укажите нужное значение, например
600 секунд
.
- В поле Сервисный аккаунт укажите
-
В блоке Смонтированный эфемерный диск:
- Нажмите Добавить эфемерный диск.
- В поле Путь монтирования укажите
/mnt
. - В поле Размер диска укажите нужное значение, например
10 ГБ
.
-
В блоке Асинхронный вызов:
- Нажмите Включить.
- В поле Сервисный аккаунт выберите
gitlab-runner-caller
.
-
-
Нажмите Создать ревизию.
-
Создайте контейнер:
yc serverless container create --name serverless-gitlab-runner
Результат:
id: bba83i1mrb5s******** folder_id: b1g681qpemb4******** created_at: "2025-09-16T06:10:03.153Z" name: serverless-gitlab-runner url: https://bba83i1mrb5s********.containers.yandexcloud.net/ status: ACTIVE
-
Создайте ревизию контейнера:
yc serverless container revision deploy \ --container-name serverless-gitlab-runner \ --runtime=http \ --cores <количество_ядер> \ --memory <объем_RAM> \ --image cr.yandex/yc/serverless/gitlab-runner \ --environment CI_SERVER_URL=https://gitlab.com \ --environment WEBHOOK_PATH=/webhook \ --secret id=<идентификатор_секрета>,version-id=<идентификатор_версии_секрета>,key=gitlab_runner_token,environment-variable=RUNNER_TOKEN \ --service-account-id <идентификатор_сервисного_аккаунта_1> \ --execution-timeout <таймаут> \ --mount type=ephemeral-disk,mount-point=/mnt,size=<размер_диска>\ --async-service-account-id <идентификатор_сервисного_аккаунта_2>
Где:
-
--container-name
— имя контейнера. -
--runtime
— режим работы. -
--cores
— количество ядер, которые доступны контейнеру, например1
. -
--memory
— требуемая память, например1GB
. -
--image
— URL Docker-образаgitlab-runner
. -
--environment
— переменные окружения:CI_SERVER_URL
— адрес GitLab CI.WEBHOOK_PATH
— путь эндпоинта вебхука.
-
--secret
— секрет Lockbox. -
--service-account-id
— идентификатор сервисного аккаунтаgitlab-runner-lockbox-payload-viewer
. -
--execution-timeout
— таймаут, например600s
. -
--mount
— параметры монтирования эфемерного диска:type=ephemeral-disk
— тип монтируемой файловой системы.mount-point
— имя точки монтирования. Директория, к которой смонтируется диск, будет доступна по пути/mnt
.size
— размер эфемерного диска в ГБ, например10GB
.
-
--async-service-account-id
— идентификатор сервисного аккаунтаgitlab-runner-caller
.
Результат:
id: bba27hejd69a******** container_id: bba83i1mrb5s******** created_at: "2025-09-18T09:38:14.528Z" image: image_url: cr.yandex/yc/serverless/gitlab-runner image_digest: sha256:ac62... environment: CI_SERVER_URL: https://gitlab.com WEBHOOK_PATH: C:/Program Files/Git/webhook resources: memory: "1073741824" cores: "1" core_fraction: "100" execution_timeout: 600s concurrency: "1" service_account_id: ajenprbpf1s3******** status: ACTIVE secrets: - id: e6qdur7h55vd******** version_id: e6qbaf927irb******** key: gitlab_runner_token environment_variable: RUNNER_TOKEN log_options: folder_id: b1g681qpemb4******** mounts: - mount_point_path: /mnt ephemeral_disk_spec: size: "10737418240" block_size: "4096" runtime: http: {} async_invocation_config: service_account_id: ajetqjm00ji8********
Совет
В случае ошибки
mounts[0].mount_point_path: Field does not match the pattern /[-_0-9a-zA-Z/]*/
экранируйте имя точки монтирования:mount-point=//mnt
-
Чтобы создать контейнер, воспользуйтесь методом REST API create для ресурса Container или вызовом gRPC API ContainerService/Create.
Чтобы создать ревизию контейнера, воспользуйтесь методом REST API deployRevision для ресурса Container или вызовом gRPC API ContainerService/DeployRevision.
Настройте вебхук в GitLab
-
В GitLab
откройте проект. -
На панели слева выберите
Settings → Webhooks. -
Нажмите Add new webhook.
-
В поле URL укажите публичный эндпоинт Serverless Containers:
https://<идентификатор_контейнера>.containers.yandexcloud.net/webhook
. -
В разделе Custom headers нажмите Add custom header и добавьте заголовки:
Header name Header value Описание Authorization
Api-Key <API-ключ>
API-ключ сервисного аккаунта gitlab-runner-caller
. Обязательно при закрытом доступе к контейнеру, иначе запрос будет отклонен. Подробнее см. Аутентифицироваться при вызове приватного контейнера через HTTPS.X-Ycf-Container-Integration-Type
async
Асинхронный вызов контейнера. В ответ на вызов платформа сразу вернет 202
. -
В разделе Trigger убедитесь, что опция
Job events
включена. -
Нажмите Add webhook.
После этого вы можете пользоваться Serverless GitLab Runners.
Совет
GitLab Runner можно дополнительно конфигурировать через переменные окружения и флаги.
Посмотрите доступные опции с помощью команды gitlab-runner run-single -h
, а также раздел документации GitLab Runner commands
Как удалить созданные ресурсы
Чтобы перестать платить за созданные ресурсы: