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 | целое. |
bool | true / false. |
duration | Go-duration (5s / 500ms / 1h30m). |
enum{a,b,c} | строка из перечисленного множества. |
string(host:port) | host:port; host — IP или DNS-имя, port — 1..65535. |
fqdn | DNS-имя (labels через точку). |
path | абсолютный путь в ФС хоста. |
default: — означает обязательное поле.
sid — идентификатор агента
Заголовок раздела «sid — идентификатор агента»| Поле | Тип | Default | Назначение |
|---|---|---|---|
sid | fqdn | FQDN хоста | Опционально. По умолчанию вычисляется как FQDN хоста. Переопределяется редко: при несовпадении sid с тем, на который выписан сертификат агента, подключение не пройдёт TLS-уровень. |
paths — файловые пути
Заголовок раздела «paths — файловые пути»Если хост следует стандартной раскладке /var/lib/soul-stack/, блок можно опустить — применятся дефолты.
| Поле | Тип | Default | Назначение |
|---|---|---|---|
paths.modules | path | /var/lib/soul-stack/modules | Кеш custom-модулей (плагинов). |
paths.seed | path | /var/lib/soul-stack/seed | Каталог mTLS-идентичности агента (сертификат + CA). Приватный ключ генерируется локально при онбординге и из этого каталога никуда не уходит. |
keeper — подключение к Keeper-кластеру
Заголовок раздела «keeper — подключение к Keeper-кластеру»Список 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.endpoints | list | — | Непустой список endpoint-ов кластера. Минимум один. |
keeper.endpoints[].host | string | — | Хост инстанса Keeper-а (FQDN или IP), общий для обеих фаз. Обязателен. |
keeper.endpoints[].event_stream_port | int (1..65535) | — | Порт долгоживущего стрима (mTLS, режим soul run). Обязателен. |
keeper.endpoints[].bootstrap_port | int (1..65535) | — | Порт онбординга (server-only TLS, режим soul init). Обязателен явно — молчаливого ухода на другой порт нет. |
keeper.endpoints[].priority | int (≥1) | 1 | Приоритет (меньше = предпочтительнее). Упорядочивает обе фазы. |
keeper.retry.max_attempts | int (≥1) | 5 | Сколько раз подряд пробовать один endpoint до перехода к следующему. |
keeper.retry.backoff.initial | duration | 1s | Начальный интервал экспоненциального бэкоффа. |
keeper.retry.backoff.max | duration | 30s | Верхняя граница бэкоффа. |
keeper.retry.backoff.jitter | bool | true | Применять ли случайный jitter к бэкоффу. |
keeper.retry.handshake_timeout | duration | 10s | Таймаут установления TLS+gRPC-соединения с одним endpoint. |
keeper.failback.enabled | bool | true | Возвращаться ли на более приоритетный endpoint после переключения вниз. |
keeper.failback.interval | duration | 1h | Как часто пытаться вернуться. |
keeper.failback.spray | duration | 10m | Амплитуда случайного разброса вокруг interval — защита от стадного эффекта при тысячах агентов. |
keeper.max_apply_size_mb | int (МиБ, ≥1) | 8 | Потолок размера одного входящего сообщения от Keeper-а (пачка отрендеренных задач). Должен быть ≥ send-лимиту Keeper-а (listen.grpc.event_stream.max_apply_size_mb в keeper.yml); дефолты обеих сторон совпадают (8 МиБ). |
keeper.tls.ca | path | — | CA-сертификат кластера: им агент валидирует серверную сторону при mTLS-handshake. Клиентский сертификат и ключ лежат в paths.seed. |
В push-режиме блок keeper игнорируется — план приходит через stdin, а не по стриму.
soulprint — факты о хосте
Заголовок раздела «soulprint — факты о хосте»| Поле | Тип | Default | Назначение |
|---|---|---|---|
soulprint.refresh_interval | duration | 5m | Как часто агент пересобирает факты о системе и (в pull) отдаёт обновление по стриму. |
Набор собираемых фактов (семейство ОС, дистрибутив, архитектура, пакетный менеджер, init-система, ядро, CPU, память, сеть) фиксирован исполняемым файлом и в конфиге не декларируется.
cleanup — локальная чистка кеша
Заголовок раздела «cleanup — локальная чистка кеша»Применяется в pull-режиме (демон периодически чистит кеш). В push чистка идёт со стороны Keeper-а.
| Поле | Тип | Default | Назначение |
|---|---|---|---|
cleanup.modules_ttl_days | int (дней) | 30 | Сколько дней неиспользуемая версия модуля живёт в кеше до удаления. |
cleanup.run_interval | duration | 24h | Как часто демон проходит по кешу. |
logging
Заголовок раздела «logging»Поведение симметрично Keeper-у: без logging.file — вывод в stderr без ротации; с файлом — встроенная ротация без logrotate.
| Поле | Тип | Default | Назначение |
|---|---|---|---|
logging.level | enum{debug,info,warn,error} | info | Уровень логирования. |
logging.format | enum{json,text} | json | json для машинной обработки, text для человека. |
logging.file | path | — (stderr) | Путь к лог-файлу. Пусто — stderr без ротации. |
logging.rotation.max_size_mb | int (МБ) | 50 | Размер файла до ротации. |
logging.rotation.max_age_days | int (≥0) | 7 | Сколько дней хранить архив. |
logging.rotation.max_files | int | 5 | Сколько архивов держать. |
logging.rotation.compress | bool | true | Сжимать ли архивы. |
metrics
Заголовок раздела «metrics»Публикация метрик агента. В отличие от 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.enabled | bool | true | Включить публикацию. При false listener не поднимается. |
metrics.listen | string(host:port) | 127.0.0.1:9091 | Адрес /metrics. По умолчанию loopback — наружу не торчит. |
metrics.basic_auth.enabled | bool | false | Включить Basic-auth. Нужен при bind не на loopback (scrape с другого хоста). |
metrics.basic_auth.username | string | — | Имя пользователя. Обязателен при enabled: true. |
metrics.basic_auth.password_file | path | — | Путь к файлу с паролем (одна строка). Источник — файл, не Vault: у агента нет Vault-клиента. Plaintext в YAML запрещён. Права на файл — забота оператора (рекомендуется 0400). |
otel: enabled: true endpoint: "otel-collector.example.com:4317"OpenTelemetry — push: при включении агент сам отправляет трейсы в OTLP-receiver. В дефолтной поставке принимающей стороной может быть Keeper-инстанс с включённым приёмом OTLP.
| Поле | Тип | Default | Назначение |
|---|---|---|---|
otel.enabled | bool | false | Включить OTLP-экспорт. |
otel.endpoint | string(host:port) | — | Адрес OTLP-receiver-а (gRPC). Обязателен при enabled: true. |
otel.export_metrics | bool | false | Опц. push метрик по OTLP. На текущем этапе экспортируются только трейсы. |
plugin_runtime
Заголовок раздела «plugin_runtime»Lifecycle плагинов на Soul-стороне (custom-модули). Структура и дефолты симметричны Keeper-у (различается только путь к каталогу сокетов). Полная таблица полей — keeper.yml → plugin_runtime; на агенте socket_dir по умолчанию /var/run/soul-stack/plugins/.
hot_reload
Заголовок раздела «hot_reload»Структура и дефолты идентичны Keeper-у (enable_signal / enable_inotify / audit_correlation_id), см. keeper.yml → hot_reload. На агенте hot-reload работает в pull-режиме по SIGHUP; в push-режиме не применим (процесс короткоживущий, файла на диске нет).
Hot-reload
Заголовок раздела «Hot-reload»В pull-режиме демон перечитывает soul.yml по SIGHUP: parse → валидация → атомарная подмена. Ошибка валидации оставляет текущее состояние нетронутым.
Без перезапуска применяются: уровень логирования, параметры retry/failback, интервал сборки фактов, параметры локальной чистки, политики плагинов.
Перезапуск нужен для: sid, путей (paths.*), endpoint-ов Keeper-а, TLS-CA, recv-лимита, адреса/auth метрик, OTel-экспортёра, путей и параметров ротации логов.
API/MCP-путь reload (как у Keeper-а) на агенте в текущем релизе не предусмотрен. Централизованная раскатка soul.yml — через вашу систему доставки конфигов; после получения нового файла агенту шлётся SIGHUP.
Что в soul.yml НЕ лежит
Заголовок раздела «Что в soul.yml НЕ лежит»- Блок
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, онбординг.