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

soul.yml

Конфиг агента на управляемом хосте. Один файл на хост, по соглашению — /etc/soul/soul.yml (исполняемый файл принимает --config <path>).

Конфиг нужен в pull-режиме (демон держит долгоживущий стрим к Keeper-у). В push-режиме большая часть полей не используется: Keeper передаёт агенту уже отрендеренный план прогона через stdin, а не через постоянную конфигурацию. Сырой Destiny/Essence на хост не попадает ни в одном из режимов — рендер делает Keeper.

У агента нет блока auth и нет Vault-клиента. Аутентификация к Keeper-у — только по mTLS (клиентский сертификат, выпущенный при онбординге). Это сознательная мера изоляции: агенту нечем читать секреты из Vault.

ЗаписьСмысл
stringстрока UTF-8.
intцелое.
booltrue / false.
durationGo-duration (5s / 500ms / 1h30m).
enum{a,b,c}строка из перечисленного множества.
string(host:port)host:port; host — IP или DNS-имя, port1..65535.
fqdnDNS-имя (labels через точку).
pathабсолютный путь в ФС хоста.

default: — означает обязательное поле.

ПолеТипDefaultНазначение
sidfqdnFQDN хостаОпционально. По умолчанию вычисляется как FQDN хоста. Переопределяется редко: при несовпадении sid с тем, на который выписан сертификат агента, подключение не пройдёт TLS-уровень.

Если хост следует стандартной раскладке /var/lib/soul-stack/, блок можно опустить — применятся дефолты.

ПолеТипDefaultНазначение
paths.modulespath/var/lib/soul-stack/modulesКеш custom-модулей (плагинов).
paths.seedpath/var/lib/soul-stack/seedКаталог mTLS-идентичности агента (сертификат + CA). Приватный ключ генерируется локально при онбординге и из этого каталога никуда не уходит.

Список endpoint-ов с приоритетами (fallback-list), retry-policy, failback и путь к CA. Агент сам инициирует соединение — на хосте не нужно открывать входящие порты.

keeper:
endpoints:
- host: keeper-1.example.com
event_stream_port: 8443 # mTLS, режим soul run
bootstrap_port: 9442 # server-only TLS, режим soul init
- host: keeper-2.example.com
event_stream_port: 8443
bootstrap_port: 9442
priority: 2 # ниже приоритет = fallback
retry:
max_attempts: 5
backoff: { initial: 1s, max: 30s, jitter: true }
handshake_timeout: 10s
failback:
enabled: true
interval: 1h
spray: 10m
max_apply_size_mb: 8
tls:
ca: /var/lib/soul-stack/seed/ca.crt
ПолеТипDefaultНазначение
keeper.endpointslistНепустой список endpoint-ов кластера. Минимум один.
keeper.endpoints[].hoststringХост инстанса Keeper-а (FQDN или IP), общий для обеих фаз. Обязателен.
keeper.endpoints[].event_stream_portint (1..65535)Порт долгоживущего стрима (mTLS, режим soul run). Обязателен.
keeper.endpoints[].bootstrap_portint (1..65535)Порт онбординга (server-only TLS, режим soul init). Обязателен явно — молчаливого ухода на другой порт нет.
keeper.endpoints[].priorityint (≥1)1Приоритет (меньше = предпочтительнее). Упорядочивает обе фазы.
keeper.retry.max_attemptsint (≥1)5Сколько раз подряд пробовать один endpoint до перехода к следующему.
keeper.retry.backoff.initialduration1sНачальный интервал экспоненциального бэкоффа.
keeper.retry.backoff.maxduration30sВерхняя граница бэкоффа.
keeper.retry.backoff.jitterbooltrueПрименять ли случайный jitter к бэкоффу.
keeper.retry.handshake_timeoutduration10sТаймаут установления TLS+gRPC-соединения с одним endpoint.
keeper.failback.enabledbooltrueВозвращаться ли на более приоритетный endpoint после переключения вниз.
keeper.failback.intervalduration1hКак часто пытаться вернуться.
keeper.failback.sprayduration10mАмплитуда случайного разброса вокруг interval — защита от стадного эффекта при тысячах агентов.
keeper.max_apply_size_mbint (МиБ, ≥1)8Потолок размера одного входящего сообщения от Keeper-а (пачка отрендеренных задач). Должен быть ≥ send-лимиту Keeper-а (listen.grpc.event_stream.max_apply_size_mb в keeper.yml); дефолты обеих сторон совпадают (8 МиБ).
keeper.tls.capathCA-сертификат кластера: им агент валидирует серверную сторону при mTLS-handshake. Клиентский сертификат и ключ лежат в paths.seed.

В push-режиме блок keeper игнорируется — план приходит через stdin, а не по стриму.

ПолеТипDefaultНазначение
soulprint.refresh_intervalduration5mКак часто агент пересобирает факты о системе и (в pull) отдаёт обновление по стриму.

Набор собираемых фактов (семейство ОС, дистрибутив, архитектура, пакетный менеджер, init-система, ядро, CPU, память, сеть) фиксирован исполняемым файлом и в конфиге не декларируется.

Применяется в pull-режиме (демон периодически чистит кеш). В push чистка идёт со стороны Keeper-а.

ПолеТипDefaultНазначение
cleanup.modules_ttl_daysint (дней)30Сколько дней неиспользуемая версия модуля живёт в кеше до удаления.
cleanup.run_intervalduration24hКак часто демон проходит по кешу.

Поведение симметрично Keeper-у: без logging.file — вывод в stderr без ротации; с файлом — встроенная ротация без logrotate.

ПолеТипDefaultНазначение
logging.levelenum{debug,info,warn,error}infoУровень логирования.
logging.formatenum{json,text}jsonjson для машинной обработки, text для человека.
logging.filepath— (stderr)Путь к лог-файлу. Пусто — stderr без ротации.
logging.rotation.max_size_mbint (МБ)50Размер файла до ротации.
logging.rotation.max_age_daysint (≥0)7Сколько дней хранить архив.
logging.rotation.max_filesint5Сколько архивов держать.
logging.rotation.compressbooltrueСжимать ли архивы.

Публикация метрик агента. В отличие от Keeper-а (где метрики обязательны), на агенте они опциональны: не каждый хост хочет открывать порт.

metrics:
enabled: true
listen: "127.0.0.1:9091" # по умолчанию loopback — недоступен снаружи
basic_auth: # опц.; нужен только при bind не на loopback
enabled: true
username: scrape
password_file: /etc/soul/metrics-password # mode 0400, одна строка
ПолеТипDefaultНазначение
metrics.enabledbooltrueВключить публикацию. При false listener не поднимается.
metrics.listenstring(host:port)127.0.0.1:9091Адрес /metrics. По умолчанию loopback — наружу не торчит.
metrics.basic_auth.enabledboolfalseВключить Basic-auth. Нужен при bind не на loopback (scrape с другого хоста).
metrics.basic_auth.usernamestringИмя пользователя. Обязателен при enabled: true.
metrics.basic_auth.password_filepathПуть к файлу с паролем (одна строка). Источник — файл, не Vault: у агента нет Vault-клиента. Plaintext в YAML запрещён. Права на файл — забота оператора (рекомендуется 0400).
otel:
enabled: true
endpoint: "otel-collector.example.com:4317"

OpenTelemetry — push: при включении агент сам отправляет трейсы в OTLP-receiver. В дефолтной поставке принимающей стороной может быть Keeper-инстанс с включённым приёмом OTLP.

ПолеТипDefaultНазначение
otel.enabledboolfalseВключить OTLP-экспорт.
otel.endpointstring(host:port)Адрес OTLP-receiver-а (gRPC). Обязателен при enabled: true.
otel.export_metricsboolfalseОпц. push метрик по OTLP. На текущем этапе экспортируются только трейсы.

Lifecycle плагинов на Soul-стороне (custom-модули). Структура и дефолты симметричны Keeper-у (различается только путь к каталогу сокетов). Полная таблица полей — keeper.yml → plugin_runtime; на агенте socket_dir по умолчанию /var/run/soul-stack/plugins/.

Структура и дефолты идентичны Keeper-у (enable_signal / enable_inotify / audit_correlation_id), см. keeper.yml → hot_reload. На агенте hot-reload работает в pull-режиме по SIGHUP; в push-режиме не применим (процесс короткоживущий, файла на диске нет).

В pull-режиме демон перечитывает soul.yml по SIGHUP: parse → валидация → атомарная подмена. Ошибка валидации оставляет текущее состояние нетронутым.

Без перезапуска применяются: уровень логирования, параметры retry/failback, интервал сборки фактов, параметры локальной чистки, политики плагинов.

Перезапуск нужен для: sid, путей (paths.*), endpoint-ов Keeper-а, TLS-CA, recv-лимита, адреса/auth метрик, OTel-экспортёра, путей и параметров ротации логов.

API/MCP-путь reload (как у Keeper-а) на агенте в текущем релизе не предусмотрен. Централизованная раскатка soul.yml — через вашу систему доставки конфигов; после получения нового файла агенту шлётся SIGHUP.

  • Блок auth — агент аутентифицируется по mTLS, не по JWT.
  • Destiny и Essence — на хост сырыми не попадают; Keeper рендерит их у себя и передаёт готовый план.
  • Bootstrap-токен — используется однократно при онбординге (из stdin или переменной окружения), затем не хранится.
  • Список модулей и их источников — реестр модулей живёт на Keeper-е.
  • Поле version — версия сборки определяется артефактом, в конфиге не дублируется.
# sid: redis-1.prod.example.com # опц.; по умолчанию = FQDN хоста
paths:
modules: /var/lib/soul-stack/modules
seed: /var/lib/soul-stack/seed
keeper:
endpoints:
- host: keeper-1.example.com
event_stream_port: 8443
bootstrap_port: 9442
- host: keeper-2.example.com
event_stream_port: 8443
bootstrap_port: 9442
- host: keeper-dr.example.com
event_stream_port: 8443
bootstrap_port: 9442
priority: 2
retry:
max_attempts: 5
backoff: { initial: 1s, max: 30s, jitter: true }
handshake_timeout: 10s
failback:
enabled: true
interval: 1h
spray: 10m
tls:
ca: /var/lib/soul-stack/seed/ca.crt
soulprint:
refresh_interval: 5m
cleanup:
modules_ttl_days: 30
run_interval: 24h
logging:
level: info
format: json
rotation: { max_size_mb: 50, max_files: 5, compress: true }
metrics:
enabled: true
listen: "127.0.0.1:9091"
otel:
enabled: true
endpoint: "otel-collector.example.com:4317"
  • keeper.yml — конфиг Keeper-а (включая auth для операторов).
  • Конфигурация → Обзор — секреты, сквозные возможности, hot-reload в двух словах.
  • Soul — роль агента, режимы pull/push, онбординг.