Обновлена документация под новые аддоны (gitlab, redis, mongodb, kafka, kafka-ui, rabbitmq) и новую модель явного выбора зависимостей. Добавлены и унифицированы описания переключателей *_database_mode и *_redis_mode, обновлена таблица зависимостей аддонов, примеры конфигурации и список vault-секретов.
8.9 KiB
8.9 KiB
HashiCorp Vault
Self-hosted менеджер секретов с шифрованием, аудитом и fine-grained политиками доступа.
Установка
# Standalone (по умолчанию, 1 Pod)
make addon-vault
# HA (3 Pods с Raft, нужны минимум 3 ноды)
make addon-vault ARGS="-e vault_mode=ha"
# С авто-unseal через k8s Secret (homelab/dev)
make addon-vault ARGS="-e vault_auto_unseal_type=k8s"
# С AWS KMS авто-unseal (production)
make addon-vault ARGS="-e vault_auto_unseal_type=aws -e vault_aws_kms_region=us-east-1 -e vault_aws_kms_key_id=..."
# С Ingress
make addon-vault ARGS="-e vault_ingress_enabled=true -e vault_ingress_host=vault.example.com"
Первичная инициализация (ручной режим)
После установки Vault нужно инициализировать (только один раз):
# Инициализация (генерирует unseal keys + root token)
kubectl exec -n vault vault-0 -- vault operator init \
-key-shares=5 \
-key-threshold=3
# ВАЖНО: сохрани 5 unseal keys и root token в надёжное место!
# Пример вывода:
# Unseal Key 1: abc...
# Unseal Key 2: def...
# ...
# Initial Root Token: hvs.xxxxx
# Unseal (нужно подать 3 из 5 ключей)
kubectl exec -n vault vault-0 -- vault operator unseal <key1>
kubectl exec -n vault vault-0 -- vault operator unseal <key2>
kubectl exec -n vault vault-0 -- vault operator unseal <key3>
# Проверка
kubectl exec -n vault vault-0 -- vault status
Авто-unseal режимы
k8s Secret (homelab, не для production)
make addon-vault ARGS="-e vault_auto_unseal_type=k8s"
Vault автоматически инициализируется и unseal keys сохраняются в k8s Secret vault-unseal-keys.
Unsealer Deployment следит за состоянием и unseals при перезапуске.
Получить root token:
kubectl get secret vault-unseal-keys -n vault \
-o jsonpath='{.data.root_token}' | base64 -d
AWS KMS (production)
# group_vars/all/addons.yml
vault_auto_unseal_type: "aws"
vault_aws_kms_region: "us-east-1"
vault_aws_kms_key_id: "arn:aws:kms:us-east-1:..."
# group_vars/all/vault.yml
vault_aws_kms_access_key: "AKIAIOSFODNN7EXAMPLE"
vault_aws_kms_secret_key: "wJalrXUtnFEMI/K7MDENG/..."
Transit Seal (через другой Vault)
vault_auto_unseal_type: "transit"
vault_transit_address: "https://vault-primary.example.com"
vault_transit_key_name: "autounseal"
# vault.yml:
vault_transit_seal_token: "hvs.CAESIxxxxxx"
Работа с секретами
CLI (локально через port-forward)
# Port-forward
kubectl port-forward -n vault svc/vault 8200:8200 &
# Авторизация
export VAULT_ADDR=http://localhost:8200
vault login <root_token>
# Включить KV v2 engine
vault secrets enable -path=secret kv-v2
# Записать секрет
vault kv put secret/myapp/config \
db_password="supersecret" \
api_key="abc123"
# Прочитать секрет
vault kv get secret/myapp/config
vault kv get -field=db_password secret/myapp/config
CLI (из пода в кластере)
kubectl exec -n vault vault-0 -- env VAULT_ADDR=http://localhost:8200 \
vault kv put secret/myapp/config db_password="supersecret"
Kubernetes Auth Method
Позволяет подам авторизоваться через их ServiceAccount токен:
# Включить kubernetes auth
vault auth enable kubernetes
# Настроить
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc.cluster.local:443"
# Создать политику доступа
vault policy write myapp-policy - <<EOF
path "secret/data/myapp/*" {
capabilities = ["read"]
}
EOF
# Создать роль (привязка: namespace + serviceaccount → policy)
vault write auth/kubernetes/role/myapp-role \
bound_service_account_names="myapp-sa" \
bound_service_account_namespaces="myapp" \
policies="myapp-policy" \
ttl="1h"
Vault Agent Injector — секреты в YAML манифестах
Injector (установлен по умолчанию) автоматически монтирует секреты через sidecar по annotations.
Пример Pod с автоинжекцией секретов
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: myapp
spec:
template:
metadata:
annotations:
# Включаем инжектор
vault.hashicorp.com/agent-inject: "true"
# Адрес Vault (по умолчанию авто-определяется)
vault.hashicorp.com/role: "myapp-role"
# Инжектировать секрет как файл /vault/secrets/config
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
# Шаблон (опционально — форматирует вывод)
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "secret/data/myapp/config" -}}
DB_PASSWORD={{ .Data.data.db_password }}
API_KEY={{ .Data.data.api_key }}
{{- end }}
spec:
serviceAccountName: myapp-sa # должен совпадать с vault role
containers:
- name: app
image: myapp:latest
command: ["sh", "-c", "source /vault/secrets/config && ./myapp"]
Создать ServiceAccount для пода
kubectl create serviceaccount myapp-sa -n myapp
Инжекция как переменные окружения
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp-role"
vault.hashicorp.com/agent-inject-secret-env: "secret/data/myapp/config"
vault.hashicorp.com/agent-inject-template-env: |
{{- with secret "secret/data/myapp/config" -}}
export DB_PASSWORD="{{ .Data.data.db_password }}"
export API_KEY="{{ .Data.data.api_key }}"
{{- end }}
# В контейнере:
command: ["/bin/sh", "-c", "source /vault/secrets/env && exec myapp"]
Vault в Helm чартах
Через Vault Agent (annotations в values.yaml)
# values.yaml вашего чарта
podAnnotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp-role"
vault.hashicorp.com/agent-inject-secret-db: "secret/data/myapp/db"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "secret/data/myapp/db" -}}
{{ .Data.data.password }}
{{- end }}
serviceAccount:
create: true
name: myapp-sa
Через External Secrets Operator (рекомендуется — см. ESO README)
# Helm чарт не меняется — ESO создаёт k8s Secret автоматически
# Используй стандартный envFrom/secretRef в values.yaml
envFrom:
- secretRef:
name: myapp-secrets # создан ExternalSecret → Vault
AppRole Auth (для сервисов без k8s ServiceAccount)
# Включить AppRole
vault auth enable approle
# Создать роль
vault write auth/approle/role/myservice \
secret_id_ttl="720h" \
token_ttl="1h" \
token_policies="myapp-policy"
# Получить Role ID (не секретный)
vault read auth/approle/role/myservice/role-id
# Получить Secret ID (секретный, одноразовый)
vault write -f auth/approle/role/myservice/secret-id
# Авторизация через AppRole
vault write auth/approle/login \
role_id="<role_id>" \
secret_id="<secret_id>"
Аудит и мониторинг
# Включить аудит лог в stdout
vault audit enable file file_path=stdout
# Статус кластера (HA)
kubectl exec -n vault vault-0 -- vault operator members
# Grafana: метрики доступны если addon_prometheus_stack: true
# Дашборд: импортируй ID 12904 из Grafana.com
Полезные команды
# Статус
kubectl exec -n vault vault-0 -- vault status
# Список engines
kubectl exec -n vault vault-0 -- vault secrets list
# Список auth methods
kubectl exec -n vault vault-0 -- vault auth list
# Seal (экстренная блокировка)
kubectl exec -n vault vault-0 -- vault operator seal
# Raft cluster (HA)
kubectl exec -n vault vault-0 -- vault operator raft list-peers
Официальные ресурсы
- Официальный сайт: https://www.vaultproject.io/
- Официальная документация: https://developer.hashicorp.com/vault/docs
- Версии Helm chart / ПО: https://artifacthub.io/packages/helm/hashicorp/vault