Перейти к содержанию

2. Архитектура и развёртывание


Цель — уметь спроектировать и развернуть Vault для production: выбор топологии (standalone / HA), Integrated Storage (Raft) или внешний backend, TLS, seal/unseal, бэкапы и мышление про отказоустойчивость. Ниже — сравнения, комментарии и короткие примеры конфигурации.


Варианты развёртывания

Режим Когда уместен Production
Standalone PoC, dev-лаборатория, очень редкие сценарии с жёстко зафиксированным RPO/RTO Обычно нет: одна точка отказа, нет автоматического лидерства.
HA (несколько узлов) Все сценарии с SLA Стандарт: 3 или 5 узлов Raft (кворум при потере меньшинства узлов).

Best practice: даже в «внутренней» среде целиться в HA, если Vault — критический контур (аутентификация приложений, корни доверия).


Хранилище: Integrated Storage (Raft) и Consul

Backend Суть Комментарий для production
Integrated Storage (Raft) Встроенное HA-хранилище на узлах Vault Рекомендуемый путь для новых установок: меньше движущихся частей, snapshot’ы через vault operator raft snapshot.
Consul как storage Внешний кластер Consul под state Vault Legacy/наследие; новые проекты чаще выбирают Raft, если нет жёсткой причины держать Consul.

Критично: отдельно планируйте диски под Raft (низкая задержка, надёжный volume, мониторинг свободного места и I/O).


Seal и unseal

Пока кластер sealed, операционные данные не расшифровываются — API для работы с секретами недоступен (в типичной конфигурации).

Shamir Secret Sharing

  • При инициализации вы получаете несколько unseal key shares; для unseal нужно threshold из total ключей.
  • Best practice: ключи раздельно хранить (разные люди / сейф / break-glass процедура), не в одном чате и не в Git.

Auto-unseal (облачные KMS)

Провайдер Механизм в Vault (типично) Комментарий
AWS awskms IAM с минимальными правами на kms:Decrypt/Encrypt для CMK.
GCP gcpckms Сервисный аккаунт / workload identity, отдельный key ring.
Azure azurekeyvault Предпочтительно managed identity / workload identity вместо длинноживущих client secrets в конфиге.

Best practices:

  • auto-unseal не заменяет резервное копирование и runbook на полную потерю KMS/ключей;
  • после миграции с Shamir на auto-unseal зафиксируйте recovery keys / процедуру регенерации согласно документации вашей версии Vault.

TLS в production

Практика Зачем
TLS на listener Конфиденциальность токенов и ответов API в сети.
Доверенные сертификаты Корпоративный PKI или Let's Encrypt + автоматическая ротация.
api_addr / cluster_addr с HTTPS Корректная реклама адресов для Raft/API; избегать «смешанного» HTTP при срочном debug.

Комментарий: завершение TLS на reverse-proxy допустимо, если вы сохраняете end-to-end модель доверия (SNI, health checks, таймауты) и не ломаете cluster трафик между узлами.


Резервное копирование и аварийное восстановление

Тема Production-подход
Snapshot (Raft) Регулярные vault operator raft snapshot save (или snapshot agent) → хранилище вне кластера Vault, с шифрованием at-rest бэкапа и контролем доступа.
Restore Тестируйте восстановление на стенде (drill): полный цикл «snapshot → новый кластер → unseal/auto-unseal».
DR Для географического DR смотрите официальные модели (replication и требования к версии/лицензии); это отдельное решение от «просто бэкапа файлов».

Best practice: RTO/RPO зафиксировать до инцидента; бэкап без теста восстановления считается ненадёжным.


Пример: узел HA-кластера с Raft и TLS

Фрагмент vault.hcl (адаптируйте пути, node_id, адреса и имена файлов). Один узел — шаблон; на остальных меняются node_id, api_addr/cluster_addr и блок присоединения к кворуму.

# Пример production-ориентированной конфигурации (не копировать без адаптации)
ui = true

listener "tcp" {
  address         = "0.0.0.0:8200"
  tls_cert_file   = "/etc/vault/tls/vault.crt"
  tls_key_file    = "/etc/vault/tls/vault.key"
  tls_min_version = "tls12"
}

storage "raft" {
  path    = "/opt/vault/data"
  node_id = "vault-1"

  # Присоединение к уже существующему лидеру (пример статического списка)
  retry_join {
    leader_api_addr = "https://vault-2.internal:8200"
  }
  retry_join {
    leader_api_addr = "https://vault-3.internal:8200"
  }
}

api_addr     = "https://vault-1.internal:8200"
cluster_addr = "https://vault-1.internal:8201"

Комментарий: retry_join бывает static, auto (облако/Kubernetes) — выбирайте то, что соответствует вашему IaaS; главное — стабильный DNS/IP для лидера при bootstrap.


Пример: auto-unseal через AWS KMS

seal "awskms" {
  region     = "eu-central-1"
  kms_key_id = "alias/prod-vault-unseal" # или полный ARN ключа
  # endpoint / role ARN — при необходимости для VPC endpoints и явной роли
}

Best practice: отдельный CMK, отдельный IAM role на узел / на pod, минимальные действия KMS, CloudTrail на ключ.


Пример: auto-unseal через GCP Cloud KMS

seal "gcpckms" {
  project    = "my-gcp-project"
  region     = "europe-west3"
  key_ring   = "vault-prod"
  crypto_key = "vault-unseal"
}

Учётные данные — через сервисный аккаунт с правами на unwrap key, без ключей JSON в образе контейнера (Workload Identity / metadata).


Пример: auto-unseal через Azure Key Vault

seal "azurekeyvault" {
  tenant_id = "00000000-0000-0000-0000-000000000000"
  vault_name = "kv-prod-vault-unseal"
  key_name   = "vault-unseal"
  # В production: аутентификация через managed identity (см. документацию Vault для вашей версии)
}

Комментарий: не храните client_secret в репозитории; для VM используйте system-assigned identity, для AKS — workload identity.


Оперативные команды (Raft)

# Статус узла
vault status

# Участники Raft-кластера (на разрешённом по policy операторе)
vault operator raft list-peers

# Снимок состояния (делайте по расписанию и выгружайте off-cluster)
vault operator raft snapshot save /secure/backups/vault-$(date +%Y%m%d-%H%M).snap

Краткий production checklist

# Проверка
1 HA Raft, не одиночный узел без обоснования
2 TLS, корректные api_addr / cluster_addr
3 Выбран и задокументирован seal (Shamir и/или KMS)
4 Регулярные snapshot + тест restore
5 Audit device и мониторинг (лидер, sealed, latency storage)
6 Runbook: потеря кворума, потеря региона, ротация TLS

Дополнительные материалы