Обновлена документация под новые аддоны (gitlab, redis, mongodb, kafka, kafka-ui, rabbitmq) и новую модель явного выбора зависимостей. Добавлены и унифицированы описания переключателей *_database_mode и *_redis_mode, обновлена таблица зависимостей аддонов, примеры конфигурации и список vault-секретов.
290 lines
8.9 KiB
Markdown
290 lines
8.9 KiB
Markdown
# HashiCorp Vault
|
||
|
||
Self-hosted менеджер секретов с шифрованием, аудитом и fine-grained политиками доступа.
|
||
|
||
## Установка
|
||
|
||
```bash
|
||
# 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 нужно инициализировать (только один раз):
|
||
|
||
```bash
|
||
# Инициализация (генерирует 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)
|
||
```bash
|
||
make addon-vault ARGS="-e vault_auto_unseal_type=k8s"
|
||
```
|
||
Vault автоматически инициализируется и unseal keys сохраняются в k8s Secret `vault-unseal-keys`.
|
||
Unsealer Deployment следит за состоянием и unseals при перезапуске.
|
||
|
||
**Получить root token:**
|
||
```bash
|
||
kubectl get secret vault-unseal-keys -n vault \
|
||
-o jsonpath='{.data.root_token}' | base64 -d
|
||
```
|
||
|
||
### AWS KMS (production)
|
||
```yaml
|
||
# 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)
|
||
```yaml
|
||
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)
|
||
```bash
|
||
# 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 (из пода в кластере)
|
||
```bash
|
||
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 токен:
|
||
|
||
```bash
|
||
# Включить 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 с автоинжекцией секретов
|
||
```yaml
|
||
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 для пода
|
||
```bash
|
||
kubectl create serviceaccount myapp-sa -n myapp
|
||
```
|
||
|
||
### Инжекция как переменные окружения
|
||
```yaml
|
||
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 }}
|
||
```
|
||
```yaml
|
||
# В контейнере:
|
||
command: ["/bin/sh", "-c", "source /vault/secrets/env && exec myapp"]
|
||
```
|
||
|
||
## Vault в Helm чартах
|
||
|
||
### Через Vault Agent (annotations в values.yaml)
|
||
```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)
|
||
```yaml
|
||
# Helm чарт не меняется — ESO создаёт k8s Secret автоматически
|
||
# Используй стандартный envFrom/secretRef в values.yaml
|
||
envFrom:
|
||
- secretRef:
|
||
name: myapp-secrets # создан ExternalSecret → Vault
|
||
```
|
||
|
||
## AppRole Auth (для сервисов без k8s ServiceAccount)
|
||
|
||
```bash
|
||
# Включить 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>"
|
||
```
|
||
|
||
## Аудит и мониторинг
|
||
|
||
```bash
|
||
# Включить аудит лог в 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
|
||
```
|
||
|
||
## Полезные команды
|
||
|
||
```bash
|
||
# Статус
|
||
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://www.vaultproject.io/)
|
||
- Официальная документация: [https://developer.hashicorp.com/vault/docs](https://developer.hashicorp.com/vault/docs)
|
||
- Версии Helm chart / ПО: [https://artifacthub.io/packages/helm/hashicorp/vault](https://artifacthub.io/packages/helm/hashicorp/vault)
|