Перейти к основному содержимому

Исполнители

Исполнитель определяет, где раннер запускает процесс задачи. Раннер по-прежнему опрашивает сервер, получает задачу и отправляет журнал обратно; меняется только место, где работает процесс Ansible, Terraform или shell.

Исполнительrunner.executor.typeГде выполняется задачаРедакция
Локальныйlocal (по умолчанию)Дочерний процесс на хосте раннера, с его файлами, инструментами и PATH.Community
DockerdockerНовый контейнер в демоне Docker, удаляется после задачи.Pro
Kubernetesk8sНовый Pod в пространстве имён Kubernetes, удаляется после задачи.Enterprise

Исполнитель — это настройка раннера, а не сервера или шаблона. Сам сервер Semaphore всегда выполняет задачи локально; чтобы выполнять задачи в контейнерах, запустите раннер и направьте на него шаблоны с помощью тега раннера.

Выбор исполнителя​

Что нужноЧто использовать
Инструменты, установленные на одной машине, доступ к её файлам, выходные данные workflowЛокальный
Чистое окружение для каждой задачи, разные наборы инструментов для разных шаблонов, на одном или нескольких хостахDocker
Распределение задач по кластеру, RBAC и Secrets Kubernetes, без сокета DockerKubernetes

Настройка исполнителя​

Добавьте блок executor в секцию runner файла конфигурации раннера:

{
"web_host": "https://semaphore.example.com",
"runner": {
"token_file": "/var/lib/semaphore/runner_token.txt",
"executor": {
"type": "docker"
}
}
}

Или задайте переменную окружения:

SEMAPHORE_RUNNER_EXECUTOR_TYPE=docker   # or k8s

У каждого параметра есть переменная окружения; полные списки приведены на страницах Docker и Kubernetes. После смены исполнителя перезапустите раннер.

к сведению

Контейнерные исполнители входят в Pro-сборку раннера. Используйте образ semaphoreui/runner или официальный бинарный файл semaphore. Образ semaphoreui/runner-community собран без них и при запуске пишет в журнал docker executor is only available in the proprietary build.

Как выполняется задача в контейнере​

Оба контейнерных исполнителя выполняют задачу одинаково:

  1. Подготовка. Раннер создаёт общую рабочую область и кладёт секреты задачи (SSH-ключи, пароли vault, дополнительные переменные, статический инвентарь) туда, где контейнеры могут их прочитать.
  2. Клонирование. Короткоживущий вспомогательный (helper) контейнер клонирует репозиторий в /workspace/repo (git clone --depth 1 ветки задачи).
  3. Сборка. Контейнер build запускается в /workspace/repo и запускает приложение: ansible-playbook, terraform/tofu/terragrunt, bash, python3, powershell или бинарный файл пользовательского приложения. Его код выхода — результат задачи.
  4. Журнал. Вывод обоих контейнеров передаётся в журнал задачи во время их работы.
  5. Очистка. Контейнеры, тома, Secrets и ConfigMaps задачи удаляются независимо от того, завершилась задача успешно, с ошибкой или была остановлена.
ШагDockerKubernetes
Рабочая областьИменованный том semaphore-workspace-<task>-<random>Том emptyDir Pod'а
СекретыИменованный том semaphore-secrets-<task>-<random>, смонтирован только для чтенияОдин Secret или ConfigMap на каждый вид, смонтирован только для чтения
КлонированиеКонтейнер semaphore-job-<task>-<random>-cloneInit-контейнер git-clone
СборкаКонтейнер semaphore-job-<task>-<random>-buildКонтейнер build Pod'а semaphore-job-<task>-<random>
Кнопка остановкиdocker stop с cleanup_grace_seconds, затем удалениеУдаление Pod'а с cleanup_grace_seconds

Задача, остановленная из интерфейса, получает статус Stopped, как и с локальным исполнителем.

Внутри контейнера build​

ПутьСодержимое
/workspaceРабочая область с правом записи; также HOME задачи.
/workspace/repoКлонированный репозиторий; рабочий каталог.
/secrets/ssh/<key id>/id_rsaЗакрытый SSH-ключ репозитория или инвентаря. Загружается в ssh-agent до запуска приложения.
/secrets/vault/<name>Пароль Ansible vault, передаётся как --vault-id=<name>@<path>.
/secrets/extra-vars/values.jsonДополнительные переменные из Variable Group и semaphore_vars, передаются как --extra-vars @<path>.
/secrets/inventory/inventory.cfg или inventory.ymlСтатический инвентарь, хранящийся в Semaphore. Файловые инвентари читаются из репозитория.

Контейнер получает фиксированный набор переменных окружения, перечисленных в Переменные окружения задачи. Собственные env_vars, forwarded_env_vars, PATH и пути apps.* раннера в контейнер не передаются.

Образы​

В каждой задаче участвуют два образа:

ОбразПо умолчаниюДля чегоТребования
Образ buildsemaphoreui/job:latestЗапуск приложения.sh, бинарный файл приложения в PATH; для SSH-ключей ssh-agent, ssh-add, setsid.
Вспомогательный образsemaphoreui/helper:latestКлонирование репозитория (Docker также заполняет им том секретов).sh, git, ssh-agent, ssh-add.

semaphoreui/job — это Debian с Ansible 9 (ansible-core 2.16–2.17), Python 3, OpenSSH, Git, Terraform, OpenTofu и Terragrunt. Он работает от пользователя nobody, группа 0.

Образ build задаётся для раннера (image) и может быть переопределён для шаблона полем Executor image, см. Образ исполнителя. Вспомогательный образ задаётся только для раннера.

Сборка собственного образа​

Расширьте semaphoreui/job, если задачам нужны дополнительные коллекции Ansible, пакеты Python или инструменты. Контейнерные исполнители не устанавливают requirements.yml из репозитория, поэтому встройте коллекции и роли в образ:

FROM semaphoreui/job:latest

USER root
RUN pip3 install --no-cache-dir --break-system-packages hvac boto3 \
&& ansible-galaxy collection install -p /usr/share/ansible/collections \
community.general amazon.aws
USER nobody:0
docker build -t registry.example.com/semaphore/job-aws:1.0 .
docker push registry.example.com/semaphore/job-aws:1.0

Если вы собираете образ с нуля, сохраните эти свойства semaphoreui/job:

  • /workspace существует и доступен для записи пользователю, от которого работает контейнер.
  • /etc/passwd доступен для записи группе (chmod g=u /etc/passwd). Тогда контейнер, запущенный со случайным UID (OpenShift), получает запись в passwd, которая нужна OpenSSH и Git.
  • Особый entrypoint образу не нужен: исполнитель запускает свой скрипт через sh -c.

Ограничения​

По сравнению с локальным исполнителем контейнерные исполнители пока не поддерживают:

Не поддерживаетсяЧто делать вместо этого
Учётные данные инвентаря типа Login with password (пароль SSH или пароль become)Используйте SSH-ключ. Задача с таким ключом завершается ошибкой inventory login_password authentication is not supported.
Задачи Terraform, ожидающие ручного подтвержденияВключите Auto approve в шаблоне или запускайте только plan. Иначе задача завершается ошибкой terraform manual approval is not supported.
Репозитории типа LocalРабочая область остаётся пустой; используйте Git-репозиторий.
Установка requirements.yml (роли и коллекции Galaxy)Встройте их в образ.
Выходные данные workflow (SEMAPHORE_OUTPUTS_FILE)Используйте локальный исполнитель для задач, чьи выходные данные читает workflow.
Учётные данные отдельных хостов из конфигурации хостаИспользуйте локальный исполнитель.
История Git глубже последнего коммитаКлон неглубокий (--depth 1).

Ключи хостов SSH не проверяются: при клонировании новый ключ хоста принимается, а Ansible запускается с ANSIBLE_HOST_KEY_CHECKING=False.