Vault 密钥管理实践:从部署到使用
Vault 密钥管理实践:从部署到使用
前言
哥们,别整那些花里胡哨的理论。今天直接上硬菜——我在大厂一线使用 Vault 管理密钥的真实经验总结。作为一个白天写前端、晚上打鼓的硬核工程师,我对密钥管理的追求就像对鼓点节奏的把控一样严格。
背景
最近我们团队需要安全地管理数据库密码、API 密钥等敏感信息,避免硬编码在代码中。经过一周的部署和配置,我们基于 Vault 实现了完整的密钥管理体系,安全评分提升到 A+。今天就把这些干货分享给大家。
Vault 部署
1. 高可用部署
问题:生产环境需要高可用的 Vault 配置。
解决方案:直接上代码
# Vault 高可用部署 apiVersion: apps/v1 kind: StatefulSet metadata: name: vault namespace: vault spec: serviceName: vault replicas: 3 selector: matchLabels: app: vault template: metadata: labels: app: vault spec: containers: - name: vault image: hashicorp/vault:1.15.0 ports: - containerPort: 8200 name: api - containerPort: 8201 name: cluster env: - name: VAULT_ADDR value: "http://127.0.0.1:8200" - name: VAULT_CLUSTER_ADDR value: "https://$(POD_IP):8201" - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP command: - vault args: - server - -config=/vault/config/vault.hcl volumeMounts: - name: vault-config mountPath: /vault/config - name: vault-data mountPath: /vault/data resources: requests: cpu: 500m memory: 512Mi limits: cpu: 1000m memory: 1Gi volumes: - name: vault-config configMap: name: vault-config volumeClaimTemplates: - metadata: name: vault-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi2. 配置文件
问题:如何配置 Vault 使用 Consul 作为后端存储。
解决方案:
# Vault 配置 apiVersion: v1 kind: ConfigMap metadata: name: vault-config namespace: vault data: vault.hcl: | ui = true listener "tcp" { address = "0.0.0.0:8200" tls_disable = 1 } storage "consul" { address = "consul:8500" path = "vault" } seal "awskms" { region = "us-east-1" kms_key_id = "arn:aws:kms:us-east-1:123456789:key/vault-key" } telemetry { prometheus_retention_time = "30s" disable_hostname = true }密钥引擎
1. KV 引擎
问题:如何存储和读取密钥值对。
解决方案:
# 启用 KV 引擎 vault secrets enable -path=secret -version=2 kv # 写入密钥 vault kv put secret/music-app/database \ host=mysql.default.svc.cluster.local \ port=3306 \ username=music_app \ password=super_secret_password # 读取密钥 vault kv get secret/music-app/database # 更新密钥 vault kv patch secret/music-app/database password=new_password # 删除密钥 vault kv delete secret/music-app/database2. 数据库引擎
问题:如何动态生成数据库凭证。
解决方案:
# 启用数据库引擎 vault secrets enable database # 配置 MySQL 连接 vault write database/config/mysql \ plugin_name=mysql-rotate-root \ connection_url="{{username}}:{{password}}@tcp(mysql:3306)/" \ allowed_roles="music-app" \ username="vaultadmin" \ password="vaultadmin_password" # 创建角色 vault write database/roles/music-app \ db_name=mysql \ creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON musicdb.* TO '{{name}}'@'%';" \ default_ttl="1h" \ max_ttl="24h" # 生成动态凭证 vault read database/creds/music-appKubernetes 集成
1. 认证配置
问题:如何让 Kubernetes 应用访问 Vault。
解决方案:
# 启用 Kubernetes 认证 apiVersion: v1 kind: ServiceAccount metadata: name: vault-auth namespace: vault --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: vault-auth-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: vault-auth namespace: vault# 配置 Kubernetes 认证 vault auth enable kubernetes vault write auth/kubernetes/config \ token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt # 创建策略 vault policy write music-app - <<EOF path "secret/data/music-app/*" { capabilities = ["read"] } path "database/creds/music-app" { capabilities = ["read"] } EOF # 创建角色 vault write auth/kubernetes/role/music-app \ bound_service_account_names=music-app \ bound_service_account_namespaces=default \ policies=music-app \ ttl=1h2. Sidecar 注入
问题:如何自动将密钥注入到应用中。
解决方案:
# 应用部署配置 apiVersion: apps/v1 kind: Deployment metadata: name: music-app namespace: default spec: replicas: 3 selector: matchLabels: app: music-app template: metadata: annotations: vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/role: "music-app" vault.hashicorp.com/agent-inject-secret-database: "secret/data/music-app/database" vault.hashicorp.com/agent-inject-template-database: | {{ with secret "secret/data/music-app/database" }} export DB_HOST="{{ .Data.data.host }}" export DB_PORT="{{ .Data.data.port }}" export DB_USER="{{ .Data.data.username }}" export DB_PASS="{{ .Data.data.password }}" {{ end }} labels: app: music-app spec: serviceAccountName: music-app containers: - name: music-app image: music-app:v1.0.0 command: ["sh", "-c"] args: - source /vault/secrets/database && node app.js最佳实践
密钥轮换:
- 定期轮换密钥
- 使用动态密钥
- 配置密钥过期时间
访问控制:
- 使用最小权限原则
- 配置细粒度策略
- 定期审计访问日志
高可用性:
- 部署多节点集群
- 配置自动故障转移
- 定期备份数据
监控告警:
- 监控 Vault 状态
- 配置告警规则
- 审计所有操作
常见问题与解决方案
1. 认证失败
问题:应用无法通过 Kubernetes 认证访问 Vault。
解决方案:
- 检查 ServiceAccount 配置
- 验证角色绑定
- 检查 JWT Token
2. 密钥泄露
问题:密钥在日志中泄露。
解决方案:
- 配置日志脱敏
- 使用临时密钥
- 定期轮换密钥
3. 性能问题
问题:Vault 响应缓慢。
解决方案:
- 优化存储后端
- 配置缓存
- 水平扩展
4. 数据丢失
问题:Vault 数据丢失。
解决方案:
- 定期备份
- 配置高可用
- 测试恢复流程
