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

Подготовка инфраструктуры под Keeper

Keeper не поставляет свои внешние зависимости в комплекте — он их потребляет. Перед первым запуском вы поднимаете и настраиваете три обязательных компонента самостоятельно: PostgreSQL, Redis и Vault. Контур обязателен целиком: Keeper проверяет каждый на старте и не стартует, если любой недоступен или, в случае Vault, запечатан.

Эта страница — requirements-first: сначала что обязательно нужно, потом тюнинг и масштабирование. Контракт полей конфига здесь не дублируется — за ним идите в keeper.yml. Минимальный сквозной demo-сценарий поднятия инфры — Quick Start → Шаг 1; прод-настройка Vault (AppRole, persistent backend, auto-unseal) — на стороне core-доки, ссылки в конце.

Единственное холодное хранилище кластера: реестры агентов и операторов, каталог сервисов, состояния инкарнаций, журналы аудита. Всё, что переживает рестарт, лежит здесь.

ТребованиеЗначение
Версия14+ (рекомендуется 16 — длиннее LTS-окно). Реальный code-floor — 13 (используется встроенная gen_random_uuid()).
Расширенияникаких. Ни uuid-ossp, ни pgcrypto — UUID-генерация встроена в PostgreSQL 13+.
Драйверpgx/v5 (внутри Keeper-а, ставить ничего не нужно).
Конфигблок postgres с dsn_ref обязателен.

DSN передаётся через Vault-ссылку: прод-конвенция — dsn_ref: vault:secret/keeper/postgres (Keeper читает поле dsn из KV). Plaintext-DSN в keeper.yml парсер технически принимает, но рекомендация — всегда через Vault, чтобы секрет не лежал в конфиге.

  • Пул соединенийpostgres.pool.min / postgres.pool.max (по умолчанию у pgx max=4; задавайте min ≥ 1, max ≥ min).

  • max_connections PostgreSQL планируйте от суммарного потока: pool.max × число инстансов Keeper, с запасом ×1.5 на бэкап-инструменты и сторонних клиентов.

    Пример: 3 инстанса × pool.max: 50 = 150 соединений → max_connections ≥ 225. Default PostgreSQL (100) для такой раскладки мал.

  • Шифрование каналаsslmode=verify-full в проде (server-cert от внутренней PKI), sslmode=disable допустим только в dev.

Поля пула и их связь с воркер-пулом исполнения (acolytes) — в keeper.yml → postgres и Сайзинг acolytes.

Keeper работает с одним логическим PostgreSQL по одному DSN.

Стратегия — вертикаль PostgreSQL (больше CPU/RAM/диска) + горизонталь Keeper (stateless-инстансы за балансировщиком) + инфра-HA (Patroni/managed). Шардирование PG как способ масштабирования Keeper-а недоступно (см. выше).

Первым при большом числе душ упирается таблица audit_log — по INSERT-rate и объёму (целевой ориентир инвариант «~100k VM»). Митигации (партиционирование по дате / hot-cold-расслоение / батчинг записи) — в backlog, не в текущем релизе.

Sizing диска (ориентир):

Число душОбъём БД
до 10k VM20–50 ГБ
~100k VM100–200 ГБ (с запасом на годовой audit_log)

Операционные детали — бэкап/restore, retention, housekeeping — в core-доке infra.md → Postgres.

Горячий слой и координационная шина кластера. Хранит только эфемерное: SID-lease (какой инстанс держит стрим агента), presence Keeper-инстансов (Conclave), лидерский lease фоновых задач (Reaper), pub/sub-каналы (summons / applybus / invalidate / cancel).

ТребованиеЗначение
Версия6.2+ (рекомендуется 7.x — улучшенный ACL).
Конфигблок redis с полями под выбранный mode (addr для standalone; master_name + sentinels[] для sentinel; nodes[] для cluster).
Backupне нужен. Все ключи восстановимы естественно: lease пересоздаётся на reconnect агента, presence — на старте инстанса, лидерство — переизбранием по TTL, pub/sub эфемерен.

Пароль Redis задаётся в redis.password_ref и поддерживает обе формы:

  • vault-ref vault:secret/keeper/redis[#field] — Keeper резолвит его из Vault на старте, так же как PG DSN и JWT signing-key. Default-поле KV-секрета — password; другое поле выбирается суффиксом #field (например vault:secret/keeper/redis#sentinel под отдельный пароль sentinel-узлов). Это рекомендуемая прод-форма.
  • plaintext-строка — пароль прямо в keeper.yml (dev / тесты без Vault).
  • пустое — Redis без пароля (только dev).

Если поле в KV отсутствует или пустое — Keeper падает fail-fast на старте с понятной ошибкой (password field missing or empty).

Отдельных TLS-полей для Redis в keeper.yml нет. Работает только то, что go-redis-клиент выводит из самого адреса (схема rediss:// и системный trust-store). Терминируйте TLS на стороне Redis / прокси, если нужен шифрованный канал.

Keeper-клиент поддерживает три топологии нативно — выбирается полем redis.mode (slot-routing для cluster и master-discovery для sentinel делает сам клиент, без внешней прокси). Пустой/опущенный mode = standalone (forward-compat для старых конфигов).

modeОбязательные поляКогда
standalone (default)addr (host:port)dev / staging, один узел.
sentinelmaster_name + sentinels[] (адреса sentinel-узлов)Рекомендуемый HA-путь для типового on-premise. Single-master с автоматическим failover — проще и безопаснее cluster. Опц. sentinel_password_ref — отдельный пароль самих sentinel-узлов.
clusternodes[] (адреса узлов для bootstrap-discovery)Горизонтальное масштабирование под большой объём ключей. См. кавеат про pub/sub ниже.

Полный контракт полей блока rediskeeper.yml → redis.

maxmemory 1gb
maxmemory-policy noeviction
  • maxmemory — для целевых 100k VM достаточно ~1gb: суммарный объём всех ключей Soul Stack — порядка 10 МБ (soul:<sid>:lock × 100k ≈ 10 МБ, presence — единицы КБ, pub/sub в памяти не хранится). 1gb — с большим запасом.
  • maxmemory-policy noevictionстрого noeviction, не allkeys-lru. У каждого ключа есть собственный TTL и смысловой fallback в коде; LRU-вытеснение lease посреди его жизни даст split-brain (двойной handler одного SID, два Reaper-лидера). noeviction + запас по памяти этого не допускает.

По объёму данных standalone-Redis спокойно тянет целевые 100k VM — переход на HA-топологию диктуется требованиями к отказоустойчивости Redis, а не размером данных.

  • Для HA типового on-premise выбирайте sentinel (mode: sentinel): автоматический failover, single-master, без шардирования. Это рекомендуемый путь.
  • cluster (mode: cluster) берите осознанно — когда объём ключей перерос один master и нужно горизонтальное шардирование. Учитывайте кавеат про cluster pub/sub-broadcast (см. режимы).

Обе топологии поддержаны клиентом нативно — внешняя cluster-aware-прокси не требуется.

Операционные детали (что лежит в Redis по ключам, restore-процедура) — в core-доке infra.md → Redis.

Хранилище всех секретов инсталляции и PKI для mTLS-идентичности агентов. Обязателен и hard-required: запечатанный (sealed) Vault → Keeper работает в режиме fail-closed, флага «работать без Vault» нет и не планируется.

EngineОбязательностьЗачем
KV (v1 или v2)обязателенСекреты Keeper-а (DSN, JWT-ключ, …) и essence-секреты сервисов. Версия определяется автоматически; v2 рекомендуется (versioning + metadata; Sigil multi-anchor требует v2).
PKI (mount + role)обязателенПодпись CSR при онбординге агентов — без PKI новый агент не получит mTLS-идентичность (SoulSeed).
SSHопциональноТолько для push-режима keeper.push через Vault SSH-provider.

Версия Vault в dev/CI — 1.18.

ПараметрОбязательностьПримечание
vault.addrобязателенПустой → fail-fast на старте.
vault.auth.methodопционаленtoken (default) или approle.
vault.kv_mountопционаленDefault secret.
vault.kv_versionопционаленПусто = auto-probe; задаётся явно, только если ACL закрыл probe (см. ниже).
vault.pki_mount / vault.pki_roleнужны для онбординга агентовЧерез них подписывается CSR.

Полный контракт полей — keeper.yml → vault.

В проде Keeper аутентифицируется в Vault через AppRole (а не статический токен):

vault:
addr: "https://vault.internal:8200"
auth:
method: approle
role_id: keeper-prod # НЕ секрет — допустим inline
secret_id_file: /etc/keeper/vault-secret-id # mode 0400, абсолютный путь
pki_mount: "pki/soulstack"
pki_role: "soul-seed"
  • role_idне секрет, идентификатор роли, кладётся inline в keeper.yml.
  • secret_id — секрет; задаётся ровно одним из: secret_id_file (файл mode 0400, абсолютный путь) или secret_id_env (имя env-переменной).

В dev допустим статический root-токен (token: "root") с Vault в dev-режиме. Для прода dev-mode непригоден — он держит секреты в RAM и теряет их при каждом рестарте (потеря JWT-ключа = инвалидация всех операторских токенов, потеря PKI-корня).

Эталон — examples/keeper/vault-policy.hcl в core-репозитории. Ровно 4 пути, каждый выдаёт минимум:

PathCapabilitiesЗачем
secret/data/keeper/*readЧтение KV-секретов Keeper-а. Только read — Keeper их не пишет. Для KV v1 путь без /data/: secret/keeper/*.
pki/issue/<pki_role>updateПодпись CSR при онбординге агента (issue-эндпоинту нужен только POST).
secret/metadata/keeper/sigil-keys/*list, readReaper orphan-reconcile ключей Sigil — report-only, только имена + metadata. Только KV v2.
auth/token/renew-selfupdateПродление собственного client-token Keeper-а.

Дополнительно:

  • push через Vault SSH — добавьте путь под SSH-CA sign (ssh/sign/<role>).
  • probe версии KV требует доступа к sys/internal/ui/mounts/<mount>. Если ACL его закрывает — задайте kv_version в конфиге явно, тогда probe не выполняется.
ПутьПолеНазначениеОбязательность
secret/keeper/jwt-signing-keysigning_keyHS256-ключ подписи операторских JWTобязательно всегда (без него нет auth Архонтов)
secret/keeper/postgresdsnDSN PostgreSQLобязательно, если dsn_ref = vault-ref
secret/keeper/sigil-signing-key, secret/keeper/sigil-keys/<key_id>Подпись Sigilопционально (без него — fail-closed-деградация)
secret/keeper/providers/*credentials cloud-driver-овопционально (если используется cloud)
secret/keeper/toll-webhook-urlurlURL webhook-уведомленийопционально
secret/keeper/metrics-passwordpasswordBasic-auth на /metricsопционально
secret/keeper/ssh-host-caSSH host CA для pushопционально
secret/keeper/* (essence-секреты)резолв ${ vault(...) } в CELопционально

PKI (не KV-секрет, а engine):

Окно терминала
vault secrets enable -path=pki/soulstack pki
vault secrets tune -max-lease-ttl=87600h pki/soulstack
vault write -field=certificate pki/soulstack/root/generate/internal \
common_name="Soul Stack SoulSeed CA" ttl=87600h > /tmp/ca.crt
vault write pki/soulstack/roles/soul-seed \
allowed_domains="example.com,internal" \
allow_subdomains=true \
max_ttl=720h

Mount (pki/ или pki/soulstack/) + root cert + role (soul-seed) с allowed_domains / allow_subdomains / max_ttl. Имена путей в policy и в keeper.yml::vault.pki_mount / pki_role должны совпадать.

Аспектdevprod
Authtoken: "root" (dev-mode)AppRole + secret_id из файла/env
Backendin-memory (теряется на рестарте)persistent (raft / consul)
Unsealавто (dev-mode сам себя)auto-unseal через KMS/HSM
ТранспортHTTPHTTPS

Sealed Vault → Keeper fail-closed (ничего не резолвит, новый агент не онбордится). Прод-настройка Vault детально — в core-доке prod-setup.md.

Сводка ключевых отличий по всем трём компонентам:

Компонентdevprod
PostgreSQL sslmodedisableverify-full
PostgreSQL топологияsingle instancePatroni / managed + HA (прозрачно для Keeper)
Redis парольpassword_ref: "" (без пароля)password_ref: vault:secret/keeper/redis (резолв из Vault)
Redis топологияmode: standalone (single instance)mode: sentinel (рекомендуемый HA) или mode: cluster — нативно, без прокси
Vault authtoken: "root"AppRole (secret_id из файла/env)
Vault backenddev-mode, in-memorypersistent (raft/consul) + auto-unseal
Vault транспортHTTPHTTPS (cert через системный trust-store)

За деталями прод-настройки Vault (AppRole, persistent backend, auto-unseal, ротация JWT signing-key) — docs/keeper/prod-setup.md в core-репозитории.

  • Quick Start → Шаг 1 — поднять инфраструктуру в demo-сценарии.
  • keeper.yml — нормативный контракт полей конфига (блоки postgres / redis / vault / auth).
  • Установка — способы поставки исполняемых файлов; внешняя инфраструктура — на вас.
  • Эксплуатация — масштабирование, мониторинг, бэкап/restore, обновления.
  • Core-репозиторий (не на этом сайте): docs/operations/infra.md — операционная часть инфры (бэкап/restore, retention); docs/keeper/prod-setup.md — прод-Vault (AppRole, persistent, auto-unseal); examples/keeper/vault-policy.hcl — эталон least-privilege policy.