Начало работы в Kubernetes (Helm)
Helm-чарт по пути deploy/helm/olivares разворачивает control
plane с теми же безопасными настройками по умолчанию, что и любой другой способ:
core StatefulSet (не от root, корневая файловая система только для чтения, все
capabilities сброшены), включённый TLS, экспозиция, эквивалентная loopback
(Service типа ClusterIP — ничего публичного, пока вы сами не решите), и никаких
учётных данных по умолчанию. Отсюда вы по своему выбору подключаете
Postgres, active-passive HA, плановые зашифрованные DR-резервные копии
и DaemonSet коллекторов для распределённого приёма данных.
Всё, что приведено ниже, было отрендерено и проверено относительно чарта в этом
репозитории (helm lint + helm template, включая конфигурации HA и резервного
копирования, а также собственные предохранители чарта). Чарт требует
Kubernetes ≥ 1.25.
1. Установка по умолчанию (один узел, SQLite)
Заголовок раздела «1. Установка по умолчанию (один узел, SQLite)»-
Установка из чекаута:
Окно терминала helm install olivares deploy/helm/olivaresЭто рендерит ровно три объекта рабочих нагрузок —
StatefulSet(1 реплика, SQLite на постоянном PVC объёмом 8 Gi),ClusterIPService(8443 HTTPS, 8444 gRPC) иServiceAccountбез привилегий Kubernetes API. Пробы обращаются к/readyz(readiness — выводится из ротации, когда хранилище недоступно или реплика не лидер) и/livez(liveness — только процесс, никогда не зависимость, так что отказ хранилища никогда не вызовет цикл перезапусков). -
Прочитайте одноразовый токен настройки из лога пода (он выводится только в stdout — в Kubernetes это лог контейнера):
Окно терминала kubectl logs -l app.kubernetes.io/component=core | sed -n '/FIRST-BOOT SETUP/,/========================/p' -
Сделайте port-forward и завершите первичную настройку (тот же процесс, что и везде):
Окно терминала # Service называется <release>-olivares-core:kubectl port-forward svc/olivares-core 8443:8443curl -ksf -X POST https://127.0.0.1:8443/v1/setup \-H 'Content-Type: application/json' \-d '{"token":"<olst_ token>","email":"you@example.com","password":"<strong-password>"}'
Как вариант, вообще без Helm: репозиторий поставляет плоский манифест с теми же безопасными одноузловыми настройками по умолчанию, регенерируемый из чарта в CI:
kubectl apply -f deploy/manifests/install.yamlДля Argo CD / Flux / Kustomize (kustomize build --enable-helm) см.
deploy/gitops/ — декларативные обёртки над тем же чартом.
2. Postgres (многоарендный)
Заголовок раздела «2. Postgres (многоарендный)»Движку требуется роль базы данных с минимальными привилегиями: LOGIN, не
superuser, без BYPASSRLS — row-level security служит подстраховкой арендатора,
и движок отказывается запускаться с привилегированной ролью. Подготовьте роль с
помощью канонического deploy/postgres/01-app-role.sql (чарт может выполнить его за
вас как pre-install Job), поместите DSN в Secret и укажите его чарту:
kubectl create secret generic olivares-pg \ --from-literal=dsn='postgres://olivares_app:***@db:5432/olivares?sslmode=verify-full' \ --from-literal=admin-dsn='postgres://olivares_admin:***@db:5432/olivares?sslmode=verify-full'
helm install olivares deploy/helm/olivares \ --set core.engine=postgres \ --set postgres.dsnSecret=olivares-pg \ --set postgres.adminDsnKey=admin-dsnКлюч admin-dsn в том же Secret содержит выделенную роль NOSUPERUSER BYPASSRLS. Он опционален только если вы никогда не будете включать
резервное копирование: именно он делает полными межарендные системные
чтения — список организаций и охват многоарендности, — а включение резервного
копирования его требует (плановые зашифрованные резервные
копии). Если создать его сейчас, тот
последующий шаг сведётся к правке в одну строку.
3. Active-passive HA
Заголовок раздела «3. Active-passive HA»С Postgres в роли общего хранилища запустите несколько реплик. Одна избирается
лидером (advisory lock Postgres); резервные реплики отвечают на /readyz
503 {"status":"standby"}, так что Service маршрутизирует только к лидеру, а
резервная реплика автоматически берёт управление, когда лидер исчезает.
Две вещи структурно обязательны, и чарт обеспечивает обе (мы убедились, что предохранители рендерятся как жёсткие отказы, а не предупреждения):
| Требование | Зачем | Предохранитель чарта при отсутствии |
|---|---|---|
| core.engine=postgres | Файл SQLite локален для одного пода — он не может быть общим хранилищем. | core.replicaCount > 1 requires core.engine=postgres … |
| core.auditSigningKeySecret | Каждая реплика должна подписывать audit ledger одним и тем же ключом Ed25519, иначе hash chain раздваивается при failover. | core.replicaCount > 1 requires core.auditSigningKeySecret … |
kubectl create secret generic olivares-audit-key \ --from-file=audit-signing.key=<base64-ed25519-private-key-file>
helm install olivares deploy/helm/olivares \ --set core.engine=postgres \ --set postgres.dsnSecret=olivares-pg \ --set core.replicaCount=3 \ --set core.auditSigningKeySecret=olivares-audit-keyКанонические размеры HA — 3 или 5 реплик, active-passive. Эта одно-писательская архитектура намеренна (она соответствует модели консистентности продукта); показатели готовности к продакшену документируют уровни доступности, которые она поддерживает.
4. Плановые зашифрованные резервные копии
Заголовок раздела «4. Плановые зашифрованные резервные копии»Чарт поставляет CronJob, который запускает olivares dr backup — зашифрованный,
безопасный для непрерывности ledger пакет (снимок хранилища + ключи подписи,
запечатанные под вашим KEK + манифест chain-tip по каждому арендатору):
kubectl create secret generic dr-kek --from-literal=passphrase='<strong passphrase>'
helm upgrade olivares deploy/helm/olivares --reuse-values \ --set backup.enabled=true \ --set backup.kekSecret=dr-kek \ --set postgres.adminDsnKey=admin-dsn # на Postgres ОБЯЗАТЕЛЕН вместе с backupС core.engine=postgres чарт отказывается рендериться без
postgres.adminDsnKey, и это жёсткий отказ по существу: pg_dump резервной копии
удерживает row_security=off и аварийно завершается под ролью приложения на
таблицах с FORCE ROW LEVEL SECURITY. CronJob, подключённый к DSN приложения,
падал бы при каждом запуске — резервной копии не было бы вообще (речь не о
«тихом захвате части строк»).
Значения по умолчанию: каждые 6 часов (backup.schedule задаёт ваш RPO), 14-дневное
локальное хранение, выделенный PVC назначения. Зеркалируйте назначение вне площадки
и храните KEK отдельно от пакетов — резервная копия в том же кластере не является
аварийным восстановлением. Тренируйте восстановление через olivares dr verify;
полная процедура описана в
резервном копировании и восстановлении.
5. DaemonSet коллекторов (распределённый приём данных)
Заголовок раздела «5. DaemonSet коллекторов (распределённый приём данных)»Для распределённой топологии DaemonSet коллекторов запускает коннекторы источников
на каждом узле и отправляет наблюдения в core по gRPC — у коллекторов нет
входящего слушателя. Чарт требует токен приёма данных и принимает опциональный
материал mTLS:
helm upgrade olivares deploy/helm/olivares --reuse-values \ --set collectors.enabled=true \ --set collectors.ingestTokenSecret=olivares-ingest-token # ingest:write bearer tokenПередайте коллекторам их источники через collectors.sourcesConfig (тот же
JSON источников, что и везде), и включите mTLS с
проверкой клиентского сертификата для канала коллектор→core через
tls.grpcClientCaSecret — см. укрепление безопасности.
Мониторинг
Заголовок раздела «Мониторинг»Включите serviceMonitor, если у вас запущен Prometheus operator; в любом случае
движок предоставляет /metrics без аутентификации (он не несёт данных арендатора), а
репозиторий поставляет готовые правила алертов. См.
мониторинг с Prometheus.
Следующие шаги
Заголовок раздела «Следующие шаги»- Подключите источники: подключение источника и руководства по коннекторам.
- Тренировки на отказах: устранение неполадок — поведение при failover, обратное давление, проверка ledger.
- Изолированный кластер? Начало работы на изолированной площадке.