HTTPRoutevault.<домен> на envoy-internal (https-листенер), backend vault:8200.
Модуль just с рецептами распечатывания: vault/mod.just + mod? vault 'vault' в корневом justfile.
Ключевые решения
Чарт из git, а не из helm-репозитория HashiCorp.https://helm.releases.hashicorp.com/index.yaml отдаётся через CloudFront, который блокирует российские адреса: HelmRelease падает с 403 Forbidden. Источник — GitRepository по тегу, чарт в корне репы.
raft, а не file-бэкенд. В дефолтном конфиге чарта для standalone прописан storage "file", мы переопределяем на storage "raft" + service_registration "kubernetes" — это то, что потом позволяет расти до HA и даёт нормальные снапшоты (vault operator raft snapshot).
injector/csi выключены, authDelegator включён. Секреты приложениям раздаёт ESO, а не сайдкар-инжектор; для этого Vault должен принимать аутентификацию по service account.
wait: false у Kustomization. Готовность пода Vault наступает только после ручного vault operator init + unseal: readinessProbe — это vault status, который до распечатывания отдаёт exit 2. С wait: true объект висел бы красным, хотя чарт поставлен корректно.
upgrade.remediation.strategy: rollback (дефолт, но прописан явно) — см. раздел про данные ниже.
Что будет с данными при падении апгрейда и ремедиации
Helm при uninstall удаляет только объекты, записанные в манифест релиза: StatefulSet, Deployment, Service, ConfigMap/Secret, RBAC-объекты, StorageClasses. PVC с данными Vault в этот список не попадает: чарт не рендерит PVC, он отдаёт volumeClaimTemplates (helper vault.volumeclaims, server.dataStorage.enabled), а PVC создаёт контроллер StatefulSet — это не ресурс Helm.
k8s удаляет PVC от volumeClaimTemplates только по persistentVolumeClaimRetentionPolicy, у чарта она пустая, то есть действует дефолт Retain. Значит PVC data-vault-0 остаётся, а вместе с ним остаётся PV (zvol в rpool/data) и все данные.
Несмотря на это, для Vault явно выбран rollback: uninstall на время ремедиации уносит сам сервис, а от Vault зависят ESO и приложения. Приоритет — «остаться на прошлой рабочей ревизии», а не самолечение. uninstall остаётся у proxmox-csi, где переустановка ничего не стоит.
Реальная страховка от потери данных лежит вне Helm: ZFS-снапшоты rpool/data по расписанию и vault operator raft snapshot save (отдельным шагом после init), плюс отдельный StorageClass с reclaimPolicy: Retain для критичных томов — предложу отдельным PR.
Распечатывание: just vault unseal
Доли берутся из файла vault-unseal-keys в корне репы (переопределяется VAULT_UNSEAL_KEYS): по одному ключу на строку, строки с # игнорируются. Файл вне git — добавлен в .gitignore вместе с /vault-root-token.
В sops ключи не кладём сознательно: age-ключ sops лежит в самом кластере (секрет sops-age), поэтому любой sops-файл из этого репозитория расшифрует тот, у кого есть доступ к кластеру, и смысл ручного unseal (PVC без ключей бесполезен) исчезает. Копии — в менеджере паролей и на бумаге.
Рецепт идемпотентный: если Vault уже распечатан — ничего не делает; отправляет ровно столько долей, сколько нужно до порога; при нехватке верных долей выходит с кодом 1 и внятным сообщением, печатает итоговый статус. just vault status — просто состояние.
Проверено локально на фейковом kubectl: 3 доли из 5 → распечатан и цикл остановлен; повторный запуск → no-op; неверные доли → exit 1; отсутствующий под → exit 1; нет файла ключей → подсказка с абсолютным путём.
После мержа (руками, по шагам)
kubectl -n security get pvc,pod — PVC должен забиндиться на proxmox-local-zfs.
kubectl -n security exec -it vault-0 -- vault operator init (5 долей, порог 3) → ключи скопировать в vault-unseal-keys (chmod 600), root token и копии ключей — в менеджер паролей и офлайн.
Дальше just vault unseal (в том числе удалённо, через WireGuard) и just vault status.
DNS: статическая A-запись на RB5009 vault → 192.168.40.11 (LB-адрес envoy-internal). Сертификат — от internal-ca, браузер будет ругаться, пока CA не добавлен в доверенные на клиентах.
UI: https://vault.<домен>.
Следующий платформенный слой после хранилища: **Vault** как источник секретов для External Secrets Operator. ESO будет отдельным PR.
## Что в PR
- ns `security` + Flux-Kustomization `vault` (targetNamespace `security`, `wait: false`).
- `GitRepository` на `github.com/hashicorp/vault-helm` (tag `v0.34.1`, Chart 0.34.1 / appVersion 2.0.4), чарт берётся из корня репозитория.
- `HelmRelease` vault: `server.standalone.enabled` + интегрированный **raft** на PVC 5Gi классом `proxmox-local-zfs` (ZFS-зеркало rpool), `global.authDelegator.enabled: true`, `server.ui: true`, injector и csi выключены.
- `HTTPRoute` `vault.<домен>` на `envoy-internal` (https-листенер), backend `vault:8200`.
- Модуль `just` с рецептами распечатывания: `vault/mod.just` + `mod? vault 'vault'` в корневом justfile.
## Ключевые решения
- **Чарт из git, а не из helm-репозитория HashiCorp.** `https://helm.releases.hashicorp.com/index.yaml` отдаётся через CloudFront, который блокирует российские адреса: HelmRelease падает с `403 Forbidden`. Источник — GitRepository по тегу, чарт в корне репы.
- **raft, а не file-бэкенд.** В дефолтном конфиге чарта для standalone прописан `storage "file"`, мы переопределяем на `storage "raft"` + `service_registration "kubernetes"` — это то, что потом позволяет расти до HA и даёт нормальные снапшоты (`vault operator raft snapshot`).
- **injector/csi выключены, authDelegator включён.** Секреты приложениям раздаёт ESO, а не сайдкар-инжектор; для этого Vault должен принимать аутентификацию по service account.
- **`wait: false` у Kustomization.** Готовность пода Vault наступает только после ручного `vault operator init` + unseal: readinessProbe — это `vault status`, который до распечатывания отдаёт exit 2. С `wait: true` объект висел бы красным, хотя чарт поставлен корректно.
- **`upgrade.remediation.strategy: rollback`** (дефолт, но прописан явно) — см. раздел про данные ниже.
## Что будет с данными при падении апгрейда и ремедиации
- Helm при uninstall удаляет только объекты, записанные в манифест релиза: StatefulSet, Deployment, Service, ConfigMap/Secret, RBAC-объекты, StorageClasses. PVC с данными Vault в этот список не попадает: чарт не рендерит PVC, он отдаёт `volumeClaimTemplates` (helper `vault.volumeclaims`, `server.dataStorage.enabled`), а PVC создаёт контроллер StatefulSet — это не ресурс Helm.
- k8s удаляет PVC от `volumeClaimTemplates` только по `persistentVolumeClaimRetentionPolicy`, у чарта она пустая, то есть действует дефолт `Retain`. Значит PVC `data-vault-0` остаётся, а вместе с ним остаётся PV (zvol в `rpool/data`) и все данные.
- Несмотря на это, для Vault явно выбран `rollback`: uninstall на время ремедиации уносит сам сервис, а от Vault зависят ESO и приложения. Приоритет — «остаться на прошлой рабочей ревизии», а не самолечение. `uninstall` остаётся у proxmox-csi, где переустановка ничего не стоит.
- Реальная страховка от потери данных лежит вне Helm: ZFS-снапшоты `rpool/data` по расписанию и `vault operator raft snapshot save` (отдельным шагом после init), плюс отдельный StorageClass с `reclaimPolicy: Retain` для критичных томов — предложу отдельным PR.
## Распечатывание: `just vault unseal`
- Доли берутся из файла `vault-unseal-keys` в корне репы (переопределяется `VAULT_UNSEAL_KEYS`): по одному ключу на строку, строки с `#` игнорируются. Файл вне git — добавлен в `.gitignore` вместе с `/vault-root-token`.
- **В sops ключи не кладём сознательно:** age-ключ sops лежит в самом кластере (секрет `sops-age`), поэтому любой sops-файл из этого репозитория расшифрует тот, у кого есть доступ к кластеру, и смысл ручного unseal (PVC без ключей бесполезен) исчезает. Копии — в менеджере паролей и на бумаге.
- Рецепт идемпотентный: если Vault уже распечатан — ничего не делает; отправляет ровно столько долей, сколько нужно до порога; при нехватке верных долей выходит с кодом 1 и внятным сообщением, печатает итоговый статус. `just vault status` — просто состояние.
- Проверено локально на фейковом `kubectl`: 3 доли из 5 → распечатан и цикл остановлен; повторный запуск → no-op; неверные доли → exit 1; отсутствующий под → exit 1; нет файла ключей → подсказка с абсолютным путём.
## После мержа (руками, по шагам)
1. `kubectl -n security get pvc,pod` — PVC должен забиндиться на `proxmox-local-zfs`.
2. `kubectl -n security exec -it vault-0 -- vault operator init` (5 долей, порог 3) → ключи скопировать в `vault-unseal-keys` (chmod 600), root token и копии ключей — в менеджер паролей и офлайн.
3. Дальше `just vault unseal` (в том числе удалённо, через WireGuard) и `just vault status`.
4. DNS: статическая A-запись на RB5009 `vault` → `192.168.40.11` (LB-адрес envoy-internal). Сертификат — от `internal-ca`, браузер будет ругаться, пока CA не добавлен в доверенные на клиентах.
5. UI: `https://vault.<домен>`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Следующий платформенный слой после хранилища: Vault как источник секретов для External Secrets Operator. ESO будет отдельным PR.
Что в PR
security+ Flux-Kustomizationvault(targetNamespacesecurity,wait: false).GitRepositoryнаgithub.com/hashicorp/vault-helm(tagv0.34.1, Chart 0.34.1 / appVersion 2.0.4), чарт берётся из корня репозитория.HelmReleasevault:server.standalone.enabled+ интегрированный raft на PVC 5Gi классомproxmox-local-zfs(ZFS-зеркало rpool),global.authDelegator.enabled: true,server.ui: true, injector и csi выключены.HTTPRoutevault.<домен>наenvoy-internal(https-листенер), backendvault:8200.justс рецептами распечатывания:vault/mod.just+mod? vault 'vault'в корневом justfile.Ключевые решения
https://helm.releases.hashicorp.com/index.yamlотдаётся через CloudFront, который блокирует российские адреса: HelmRelease падает с403 Forbidden. Источник — GitRepository по тегу, чарт в корне репы.storage "file", мы переопределяем наstorage "raft"+service_registration "kubernetes"— это то, что потом позволяет расти до HA и даёт нормальные снапшоты (vault operator raft snapshot).wait: falseу Kustomization. Готовность пода Vault наступает только после ручногоvault operator init+ unseal: readinessProbe — этоvault status, который до распечатывания отдаёт exit 2. Сwait: trueобъект висел бы красным, хотя чарт поставлен корректно.upgrade.remediation.strategy: rollback(дефолт, но прописан явно) — см. раздел про данные ниже.Что будет с данными при падении апгрейда и ремедиации
volumeClaimTemplates(helpervault.volumeclaims,server.dataStorage.enabled), а PVC создаёт контроллер StatefulSet — это не ресурс Helm.volumeClaimTemplatesтолько поpersistentVolumeClaimRetentionPolicy, у чарта она пустая, то есть действует дефолтRetain. Значит PVCdata-vault-0остаётся, а вместе с ним остаётся PV (zvol вrpool/data) и все данные.rollback: uninstall на время ремедиации уносит сам сервис, а от Vault зависят ESO и приложения. Приоритет — «остаться на прошлой рабочей ревизии», а не самолечение.uninstallостаётся у proxmox-csi, где переустановка ничего не стоит.rpool/dataпо расписанию иvault operator raft snapshot save(отдельным шагом после init), плюс отдельный StorageClass сreclaimPolicy: Retainдля критичных томов — предложу отдельным PR.Распечатывание:
just vault unsealvault-unseal-keysв корне репы (переопределяетсяVAULT_UNSEAL_KEYS): по одному ключу на строку, строки с#игнорируются. Файл вне git — добавлен в.gitignoreвместе с/vault-root-token.sops-age), поэтому любой sops-файл из этого репозитория расшифрует тот, у кого есть доступ к кластеру, и смысл ручного unseal (PVC без ключей бесполезен) исчезает. Копии — в менеджере паролей и на бумаге.just vault status— просто состояние.kubectl: 3 доли из 5 → распечатан и цикл остановлен; повторный запуск → no-op; неверные доли → exit 1; отсутствующий под → exit 1; нет файла ключей → подсказка с абсолютным путём.После мержа (руками, по шагам)
kubectl -n security get pvc,pod— PVC должен забиндиться наproxmox-local-zfs.kubectl -n security exec -it vault-0 -- vault operator init(5 долей, порог 3) → ключи скопировать вvault-unseal-keys(chmod 600), root token и копии ключей — в менеджер паролей и офлайн.just vault unseal(в том числе удалённо, через WireGuard) иjust vault status.vault→192.168.40.11(LB-адрес envoy-internal). Сертификат — отinternal-ca, браузер будет ругаться, пока CA не добавлен в доверенные на клиентах.https://vault.<домен>.