HashiCorp Vault密钥管理
约 1713 字大约 6 分钟
vaultsecrets
2025-06-25
HashiCorp Vault 是业界领先的密钥管理和数据加密平台,提供集中化的密钥存储、动态密钥生成、加密即服务和细粒度的访问控制。本文将深入讲解 Vault 的架构、核心功能及其在 Kubernetes 中的集成。
Vault 架构
Seal / Unseal(封印/解封)
Vault 启动时处于 Sealed 状态,必须解封才能处理请求。Vault 使用 Shamir 密钥分割算法将 master key 分为多个 key shares:
# 初始化 Vault(生成 key shares 和 root token)
vault operator init -key-shares=5 -key-threshold=3
# 解封(需要 3 个不同的 key share)
vault operator unseal <key-share-1>
vault operator unseal <key-share-2>
vault operator unseal <key-share-3>
# 检查状态
vault statusAuto Unseal
生产环境推荐使用 Auto Unseal,将 master key 托管到云 KMS:
# vault-config.hcl
seal "awskms" {
region = "us-east-1"
kms_key_id = "arn:aws:kms:us-east-1:123456789:key/xxx-xxx"
}
# 或使用 Transit Auto Unseal(另一个 Vault 实例)
seal "transit" {
address = "https://vault-primary.example.com:8200"
token = "s.xxxxxxxxx"
disable_renewal = "false"
key_name = "autounseal"
mount_path = "transit/"
}Secret Engines(密钥引擎)
KV(Key-Value)
最常用的密钥引擎,支持版本化:
# 启用 KV v2
vault secrets enable -path=secret kv-v2
# 写入密钥
vault kv put secret/app/database \
username="admin" \
password="S3cur3P@ss!" \
host="db.example.com"
# 读取密钥
vault kv get secret/app/database
vault kv get -field=password secret/app/database
# 查看历史版本
vault kv get -version=2 secret/app/database
# 删除(软删除)
vault kv delete secret/app/database
# 永久删除
vault kv destroy -versions=1,2 secret/app/database
# 恢复软删除
vault kv undelete -versions=3 secret/app/databaseDatabase(动态数据库凭据)
# 启用 Database 引擎
vault secrets enable database
# 配置数据库连接
vault write database/config/mydb \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(db.example.com:3306)/" \
allowed_roles="readonly,readwrite" \
username="vault-admin" \
password="vault-password"
# 创建角色
vault write database/roles/readonly \
db_name=mydb \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; \
GRANT SELECT ON mydb.* TO '{{name}}'@'%';" \
revocation_statements="DROP USER '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"
# 获取动态凭据(每次返回不同的用户名/密码)
vault read database/creds/readonly
# Key Value
# lease_id database/creds/readonly/xxx
# lease_duration 1h
# username v-token-readonly-xxx
# password A1B2C3D4E5F6PKI(证书管理)
# 启用 PKI 引擎
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
# 生成根 CA
vault write pki/root/generate/internal \
common_name="Example Root CA" \
ttl=87600h
# 配置中间 CA
vault secrets enable -path=pki_int pki
vault write pki_int/intermediate/generate/internal \
common_name="Example Intermediate CA"
# 签发证书
vault write pki_int/issue/web-cert \
common_name="app.example.com" \
alt_names="*.app.example.com" \
ttl="720h"Authentication Methods(认证方法)
Kubernetes 认证
# 启用 Kubernetes 认证
vault auth enable kubernetes
# 配置(Vault 运行在 K8s 内)
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443"
# 创建角色
vault write auth/kubernetes/role/app \
bound_service_account_names=app-sa \
bound_service_account_namespaces=production \
policies=app-policy \
ttl=1hAppRole 认证
适用于机器对机器的认证场景:
# 启用 AppRole
vault auth enable approle
# 创建角色
vault write auth/approle/role/my-app \
secret_id_ttl=10m \
token_ttl=20m \
token_max_ttl=30m \
policies=app-policy
# 获取 Role ID(部署时配置)
vault read auth/approle/role/my-app/role-id
# 获取 Secret ID(按需生成)
vault write -f auth/approle/role/my-app/secret-id
# 应用登录
vault write auth/approle/login \
role_id="xxx" \
secret_id="yyy"Policies(访问策略)
策略使用 HCL 语言定义:
# app-policy.hcl
# KV 密钥读取权限
path "secret/data/app/*" {
capabilities = ["read", "list"]
}
# 数据库凭据获取权限
path "database/creds/readonly" {
capabilities = ["read"]
}
# PKI 证书签发权限
path "pki_int/issue/web-cert" {
capabilities = ["create", "update"]
}
# 禁止访问管理接口
path "sys/*" {
capabilities = ["deny"]
}
# 允许更新自己的 token
path "auth/token/renew-self" {
capabilities = ["update"]
}
# 参数化策略
path "secret/data/{{identity.entity.metadata.team}}/*" {
capabilities = ["read", "list", "create", "update"]
}# 应用策略
vault policy write app-policy app-policy.hcl
# 查看策略
vault policy read app-policy
# 测试策略
vault token create -policy=app-policyDynamic Secrets(动态密钥)
动态密钥是 Vault 的核心优势——密钥按需生成、自动过期:
支持动态密钥的引擎:
- Database:MySQL、PostgreSQL、MongoDB、MSSQL、Oracle
- AWS:IAM User、STS AssumeRole
- Azure:Service Principal
- GCP:Service Account Key、OAuth Token
- Consul:ACL Token
- PKI:X.509 证书
- SSH:签名证书或 OTP
Kubernetes Agent Sidecar Injection
Vault Agent Injector 自动将密钥注入到 Kubernetes Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
metadata:
annotations:
# 启用 Vault Agent 注入
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app"
# 注入密钥文件
vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/readonly"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "database/creds/readonly" -}}
{
"username": "{{ .Data.username }}",
"password": "{{ .Data.password }}"
}
{{- end }}
# 注入 KV 密钥
vault.hashicorp.com/agent-inject-secret-config: "secret/data/app/config"
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "secret/data/app/config" -}}
export API_KEY="{{ .Data.data.api_key }}"
export DB_URL="{{ .Data.data.database_url }}"
{{- end }}
# Agent 配置
vault.hashicorp.com/agent-pre-populate-only: "false" # 持续更新
vault.hashicorp.com/agent-cache-enable: "true"
spec:
serviceAccountName: app-sa
containers:
- name: app
image: myapp:1.0
# 密钥文件在 /vault/secrets/ 目录下
command: ["sh", "-c", "source /vault/secrets/config && ./app"]Vault CSI Provider
另一种 Kubernetes 集成方式,通过 CSI Volume 注入密钥:
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: vault-db-creds
spec:
provider: vault
parameters:
vaultAddress: "http://vault.vault:8200"
roleName: "app"
objects: |
- objectName: "db-username"
secretPath: "secret/data/app/database"
secretKey: "username"
- objectName: "db-password"
secretPath: "secret/data/app/database"
secretKey: "password"
secretObjects:
- secretName: db-creds-k8s
type: Opaque
data:
- objectName: db-username
key: username
- objectName: db-password
key: password
---
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
serviceAccountName: app-sa
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: secrets
mountPath: /mnt/secrets
readOnly: true
volumes:
- name: secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: vault-db-creds总结
Vault 的核心价值在于将密钥管理从分散变为集中、从静态变为动态:
- 动态密钥 按需生成、自动过期,大幅降低泄露风险
- Kubernetes 集成 通过 Agent Sidecar 或 CSI Provider 无缝注入密钥
- 细粒度策略 精确控制每个应用能访问哪些密钥
- 审计日志 记录所有密钥访问操作,满足合规要求
- Auto Unseal 使用云 KMS 实现自动解封,提高运维效率
- PKI 引擎 集中管理证书生命周期,自动续期
贡献者
更新日志
2026/3/14 13:09
查看所有更新日志
9f6c2-feat: organize wiki content and refresh site setup于