0fb20dc8d4
Triage card для on-call: где взять unseal-keys (1Password placeholder, уточнить с DevOps lead), как запустить script либо ручную процедуру, что проверить после, troubleshooting типовых проблем. Также: §7 — план миграции на auto-unseal (Transit / Yandex KMS) когда определимся с master Vault или KMS-backend.
139 lines
6.5 KiB
Markdown
139 lines
6.5 KiB
Markdown
# Runbook: Vault unseal (staging / prod)
|
||
|
||
**Когда использовать:** Vault на кластере залип в `Sealed=true` после reboot
|
||
ноды или manual seal. Признаки:
|
||
- Spring Boot pod'ы (`ordinis-app`, `ordinis-read-api`, `ordinis-projection-writer`)
|
||
стоят в `Init:0/1`.
|
||
- В логах `vault-agent-init` контейнера: `Vault is sealed`, error 503 на
|
||
`auth/kubernetes/login`.
|
||
- `kubectl exec -n config vault-0 -- vault status` → `Sealed: true`.
|
||
|
||
**Auto-unseal сейчас НЕ настроен** (v1 closure backlog: Transit secret engine
|
||
с master Vault либо Yandex Cloud KMS). До миграции — ручная процедура ниже.
|
||
|
||
---
|
||
|
||
## 1. Где взять unseal-ключи
|
||
|
||
Ключи Shamir, threshold **3 из 5**. Хранение:
|
||
|
||
- **Corporate 1Password** — vault `Ordinis НСИ ЦУОД`:
|
||
- `vault-staging-unseal-keys` — для cluster.265 (192.168.100.161)
|
||
- `vault-prod-unseal-keys` — для cluster.142 (192.168.100.142)
|
||
- **Резерв** (cold storage) — у DevOps lead в KeePass.
|
||
|
||
Доступ к 1Password vault — у списка инженеров с on-call. При расширении —
|
||
добавлять через 1Password admin. Никогда не пересылать ключи в Slack /
|
||
Telegram / email.
|
||
|
||
> ⚠️ **При утере 5 из 5 ключей:** Vault инициализируется заново → ВСЕ
|
||
> secrets потеряны (postgres passwords, Kafka SASL, Keycloak signing keys
|
||
> в K8s secrets — отдельно). Plan: получить root token + replay `setup.sh` +
|
||
> заново положить secrets из 1Password (Postgres backup + Vault: писать
|
||
> только в зеркало). Делать только с письменным разрешением tech lead.
|
||
|
||
## 2. Быстрый unseal (script)
|
||
|
||
```bash
|
||
cd ~/code/ordinis-infra/k8s/vault
|
||
|
||
# staging
|
||
./unseal.sh staging "<KEY_1>" "<KEY_2>" "<KEY_3>"
|
||
|
||
# prod
|
||
./unseal.sh prod "<KEY_1>" "<KEY_2>" "<KEY_3>"
|
||
```
|
||
|
||
Скрипт делает:
|
||
|
||
1. Pull kubeconfig с ноды (если ещё не скачан).
|
||
2. Проверяет `vault status` — если уже unsealed, выходит.
|
||
3. Применяет 3 ключа последовательно через `vault operator unseal`.
|
||
4. Проверяет `Sealed: false`.
|
||
5. Force-deletes Spring Boot pod'ы — vault-agent-init иначе ждёт backoff
|
||
до 3+ минут на следующую попытку auth.
|
||
|
||
После — `kubectl get pods -n ordinis-{env}` показывает `2/2 Running`
|
||
через ~2 минуты.
|
||
|
||
## 3. Ручной unseal (если script недоступен)
|
||
|
||
```bash
|
||
# 1. Получить kubeconfig
|
||
ssh root@192.168.100.161 "cat /etc/kubernetes/admin.conf" > /tmp/kc-161
|
||
sed -i '' 's|server: https://[^:]*:|server: https://192.168.100.161:|' /tmp/kc-161
|
||
export KUBECONFIG=/tmp/kc-161
|
||
|
||
# 2. Проверить статус
|
||
kubectl exec -n config vault-0 -- vault status
|
||
|
||
# 3. Применить 3 ключа (по одному)
|
||
kubectl exec -n config vault-0 -- vault operator unseal '<KEY_1>'
|
||
kubectl exec -n config vault-0 -- vault operator unseal '<KEY_2>'
|
||
kubectl exec -n config vault-0 -- vault operator unseal '<KEY_3>'
|
||
|
||
# 4. Убедиться Sealed: false
|
||
kubectl exec -n config vault-0 -- vault status
|
||
|
||
# 5. Перезапустить Spring Boot pod'ы
|
||
kubectl delete pod -n ordinis-staging \
|
||
-l 'app.kubernetes.io/name in (ordinis-app,ordinis-read-api,ordinis-projection-writer)' \
|
||
--grace-period=0 --force
|
||
|
||
# 6. Проверить
|
||
kubectl get pods -n ordinis-staging
|
||
```
|
||
|
||
## 4. Подтверждение что всё работает
|
||
|
||
```bash
|
||
# read-api
|
||
curl -sk --resolve ordinis.k8s.265.nstart.cloud:443:192.168.100.161 \
|
||
https://ordinis.k8s.265.nstart.cloud/api/v1/spacecraft/records?lang=ru-RU \
|
||
| jq 'length'
|
||
# → должно вернуть число > 0
|
||
|
||
# admin
|
||
curl -sk -o /dev/null -w "%{http_code}\n" \
|
||
--resolve ordinis.k8s.265.nstart.cloud:443:192.168.100.161 \
|
||
"https://ordinis.k8s.265.nstart.cloud/api/v1/admin/audit?page=0&size=5"
|
||
# → 200
|
||
```
|
||
|
||
## 5. Эскалация / проблемы
|
||
|
||
| Симптом | Что делать |
|
||
|------------------------------------------------------|--|
|
||
| `vault status` → `connection refused` | Pod `vault-0` не Running. `kubectl get pods -n config` + `kubectl describe`. |
|
||
| `unseal` принимает ключ но Sealed остаётся true | Проверить count `Unseal Progress` — может нужен 4-й ключ если threshold увеличили. |
|
||
| Все 3 ключа отвергает (`invalid key`) | Whitespace / обрезанные символы. Скопировать заново из 1Password (полное поле). |
|
||
| Pod'ы Spring Boot не поднимаются после unseal | `kubectl logs <pod> -c vault-agent-init` — могут быть policy/role миграции после изменений. |
|
||
| Consul backend (Vault использует Consul) недоступен | `kubectl get pods -n config consul-server-0` + `kubectl logs`. |
|
||
|
||
При 30+ минут downtime → эскалация tech lead → решение о переносе
|
||
prod-нагрузки на запасной кластер либо публичная коммуникация в SLA-канал.
|
||
|
||
## 6. Связанные документы
|
||
|
||
- Установка Vault с нуля: `ordinis-infra/k8s/vault/setup.sh`
|
||
- Архитектура auth: `ordinis-auth/.../{ScopeContext,SecurityConfig}.java`
|
||
- Список секретов в Vault: `secret/ordinis/cuod/` (postgres, kafka, redis)
|
||
|
||
## 7. Переход к auto-unseal (TODO для v1 closure)
|
||
|
||
Когда будет master Vault либо Yandex Cloud KMS:
|
||
|
||
1. Добавить `seal "transit"` либо `seal "yandexcloudkms"` stanza в vault config
|
||
ConfigMap (`config/vault-config`).
|
||
2. Запустить migration:
|
||
```
|
||
kubectl exec -n config vault-0 -- vault operator unseal -migrate KEY_1
|
||
kubectl exec -n config vault-0 -- vault operator unseal -migrate KEY_2
|
||
kubectl exec -n config vault-0 -- vault operator unseal -migrate KEY_3
|
||
```
|
||
3. После миграции существующие Shamir-keys больше не работают — выдаются
|
||
Recovery Keys (5 шт, тот же threshold 3) для emergency rekey/operator-init
|
||
операций.
|
||
4. Обновить этот runbook: основной случай — auto-unseal, ручной unseal
|
||
только при downtime master Vault / KMS.
|