密钥管理解决密码、证书、API Key的安全存储、分发和轮换。硬编码密钥是最常见的安全漏洞。
┌────────────────────────────────────────────────┐
│ 应用层 │
│ K8s Pod → CSI Driver → Vault/Sealed Secrets │
└────────────────────┬───────────────────────────┘
┌────────────────┼───────────────┐
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────────┐
│ Vault │ │SealedSec │ │ AWS KMS │
│动态密钥 │ │Git安全 │ │ 信封加密 │
│自动轮换 │ │集群解密 │ │ HSM保护 │
└───┬────┘ └──────────┘ └──────────────┘
▼
┌────────────────────┐
│ 密钥轮换+审计日志 │
└────────────────────┘# 部署Vault
docker run -d --name vault -p 8200:8200 \
-e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' \
-e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \
hashicorp/vault:latest
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='myroot'
vault secrets enable -path=secret kv-v2
vault kv put secret/myapp/database username="appuser" password="S3cureP@ss!" url="postgresql://db:5432/myapp"
vault kv put secret/myapp/api-keys stripe-key="sk_live_xxx" sendgrid-key="SG.xxx"
vault kv get secret/myapp/database
vault kv get -field=password secret/myapp/database
# 创建策略(最小权限)
cat > app-policy.hcl << 'EOF'
path "secret/data/myapp/*" { capabilities = ["read"] }
path "secret/metadata/myapp/*" { capabilities = ["list"] }
EOF
vault policy write myapp-readonly app-policy.hcl
# 创建AppRole
vault auth enable approle
vault write auth/approle/role/myapp token_policies="myapp-readonly" token_ttl=1h token_max_ttl=4h
vault read auth/approle/role/myapp/role-id
vault write -f auth/approle/role/myapp/secret-idhelm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault --set "server.dev.enabled=true" --set "csi.enabled=true"
vault auth enable kubernetes
vault write auth/kubernetes.config kubernetes_host="https://kubernetes.default.svc:443"
cat > spc-vault.yaml << 'EOF'
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata: {name: vault-myapp}
spec:
provider: vault
parameters:
vaultAddress: "http://vault.default.svc:8200"
roleName: "myapp"
objects: |
- objectName: "db-password"
secretPath: "secret/data/myapp/database"
method: "GET"
secretKey: "password"
EOF
kubectl apply -f spc-vault.yamlkubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.25.0/controller.yaml
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.25.0/kubeseal-linux-amd64 -O /usr/local/bin/kubeseal
chmod +x /usr/local/bin/kubeseal
# 加密Secret(可安全提交到Git)
kubectl create secret generic db-credentials \
--from-literal=username=appuser --from-literal=password=S3cureP@ss \
--dry-run=client -o yaml | kubeseal --format yaml > sealed-secret.yaml
kubectl apply -f sealed-secret.yaml
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -daws kms create-key --description "MyApp encryption key"
aws kms create-alias --alias-name alias/myapp-key --target-key-id
# 加密/解密
aws kms encrypt --key-id alias/myapp-key --plaintext "SuperSecret" --query CiphertextBlob --output text | base64 -d > encrypted.bin
aws kms decrypt --ciphertext-blob fileb://encrypted.bin --query Plaintext --output text | base64 -d
# 密钥轮换(每年自动)
aws kms enable-key-rotation --key-id ┌────────────────────────────────────────────────┐
│ 应用层 │
│ K8s Pod → CSI Driver → Vault/Sealed Secrets │
└────────────────────┬───────────────────────────┘
┌────────────────┼───────────────┐
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────────┐
│ Vault │ │SealedSec │ │ AWS KMS │
│动态密钥 │ │Git安全 │ │ 信封加密 │
│自动轮换 │ │集群解密 │ │ HSM保护 │
└───┬────┘ └──────────┘ └──────────────┘
▼
┌────────────────────┐
│ 密钥轮换+审计日志 │
└────────────────────┘vault status
# Sealed: true → 需要Unseal Key
vault operator unseal
vault operator unseal
# 生产模式需要3个Key中的2个(Shamir算法)
# Key丢失 → 数据不可恢复! 掌握Vault动态密钥、K8s CSI集成、Sealed Secrets、KMS信封加密
| 密钥类型 | 轮换周期 | 轮换方式 | 紧急处理 |
|---|---|---|---|
| 数据库密码 | 90天 | Vault动态凭证 | 立即轮换 |
| API Key | 180天 | 双Key交替 | 禁用+重新生成 |
| TLS证书 | 90天 | Let's Encrypt自动 | 手动续签 |
| SSH密钥 | 1年 | 生成新密钥对 | 删除旧公钥 |
| 加密密钥(KMS) | 1年 | 自动轮换 | 重新加密 |
#!/bin/bash
# secret-leak-response.sh — 密钥泄露应急
LEAKED_KEY="${1:?密钥名称}"
echo "🚨 密钥泄露应急响应: $LEAKED_KEY"
# 1. 立即禁用泄露的密钥
vault kv metadata delete secret/$LEAKED_KEY
# 2. 生成新密钥
NEW_PASS=$(openssl rand -base64 24)
vault kv put secret/$LEAKED_KEY password="$NEW_PASS"
# 3. 更新所有使用该密钥的服务
kubectl rollout restart deployment -l app=myapp
# 4. 记录审计日志
vault audit log file_path=/var/log/vault-audit.log
echo "✅ 密钥已轮换,服务已重启"