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

Архитектура

У установки Semaphore есть три обязательные части: один серверный процесс, одна база данных и место, где выполняются задачи. Всё остальное — раннеры, Redis, обратный прокси, провайдер идентификации — необязательно и добавляется, когда появляется конкретная потребность.

Составные части

Сервер

Один бинарный файл на Go. В него встроен собранный веб-интерфейс, поэтому один процесс обслуживает UI, REST API и WebSocket-эндпоинт /api/ws, который передаёт вывод задач в открытые браузеры. По умолчанию он слушает порт 3000.

Внутри этого процесса одновременно работает несколько подсистем:

ЧастьЗа что отвечает
HTTP API и UIВсё, к чему обращаются браузер и API-клиенты.
Пул задачОчередь задач, ограничения параллельности и их состояние.
ПланировщикЗапускает шаблоны по их cron-расписаниям.
Локальный исполнительВыполняет задачи на самом сервере, когда их не берёт удалённый раннер.
НотификаторОтправляет оповещения по завершении задач.

База данных

SQLite, MySQL или PostgreSQL — выбирается опцией dialect. В ней хранятся проекты, шаблоны, инвентари, расписания, пользователи, роли, история задач и зашифрованное содержимое Хранилища ключей. Это единственное, что обязательно резервировать: всё остальное можно восстановить заново.

SQLite используется по умолчанию и подходит для одного сервера. Выбирайте PostgreSQL или MySQL, когда от сервиса зависит несколько человек, и обязательно — когда узлов больше одного.

Файловый кеш

Каталог из tmp_path (по умолчанию /tmp/semaphore) хранит склонированные репозитории и рабочий каталог каждого запуска. Это кеш, а не хранилище: его удаление стоит одного дополнительного клонирования на проект. Кнопка Clear cache в настройках проекта делает именно это.

Этот кеш держит та машина, которая выполняет задачу, — сервер, когда задачи выполняются локально, и каждый раннер, когда нет.

Где выполняются задачи

По умолчанию сервер выполняет задачи сам — в своей файловой системе и со своим сетевым доступом. Это самая простая схема и правильный выбор для небольшой команды, управляющей хостами, до которых сервер и так дотягивается.

Добавление раннеров разделяет эти роли. Раннер — это тот же бинарный файл, запущенный командой semaphore runner start. У него нет подключения к базе данных и он не открывает входящих портов: он опрашивает сервер по HTTPS с bearer-токеном, получает задание, клонирует репозиторий, запускает инструмент и передаёт вывод обратно. Раннеры позволяют

  • разместить выполнение внутри сети, до которой сервер не дотягивается,
  • держать учётные данные для продуктива на машине, которая не обслуживает веб-интерфейс,
  • распределить нагрузку между несколькими машинами и
  • (в Pro) направить задачу на конкретный раннер с помощью меток.

Каждый раннер выбирает способ запуска задания в своей опции executor.type:

ИсполнительГде выполняется задание
localКак процесс на хосте раннера, в tmp_path.
dockerВ контейнере, который раннер запускает для этого задания, а затем удаляет.
k8sВ Pod'е, который раннер создаёт в вашем кластере, а затем удаляет.

Порты и направления

Каждое соединение исходящее — от того компонента, который его инициирует, и именно это позволяет использовать раннеры через сетевые границы.

ОткудаКудаЗачем
Браузер, API-клиентСервер :3000UI, REST API, WebSocket.
СерверБаза данныхВсё постоянное состояние.
Сервер, раннерGit-удалённые репозиторииКлонирование репозиториев.
Сервер, раннерУправляемые хосты, облачные APIСобственно автоматизация.
РаннерСервер :3000Опрос заданий, передача вывода.
СерверLDAP, OIDC, SMTP, чат-вебхукиВход и уведомления.

Масштабирование

Две оси масштабируются независимо.

Больше выполнения — больше раннеров. Сервер остаётся одним процессом, а задачи распределяются между подключёнными раннерами.

Больше доступности — больше серверов. Несколько узлов работают с одной базой данных PostgreSQL или MySQL и с Redis для распределённых блокировок, общего состояния очереди и pub/sub, за балансировщиком нагрузки с поддержкой WebSocket. Это высокая доступность, возможность редакции Enterprise. SQLite для неё использовать нельзя.

Что дальше