密钥管理
学习目标
- 理解密钥管理的重要性
- 掌握 Secrets 的创建和使用
- 了解密钥管理的最佳实践
核心概念
一句话解释
Kubernetes Secrets 用于存储和管理敏感信息,如密码、Token、证书等。
密钥管理挑战
┌─────────────────────────────────────────────────────────────┐
│ 密钥管理挑战 │
├─────────────────────────────────────────────────────────────┤
│ 存储安全 │
│ ├── 明文存储风险 │
│ ├── etcd 加密 │
│ └── 外部密钥管理 (Vault) │
├─────────────────────────────────────────────────────────────┤
│ 访问控制 │
│ ├── RBAC 权限管理 │
│ ├── 命名空间隔离 │
│ └── Pod 级别访问 │
├─────────────────────────────────────────────────────────────┤
│ 生命周期 │
│ ├── 密钥轮换 │
│ ├── 过期管理 │
│ └── 审计追踪 │
└─────────────────────────────────────────────────────────────┘
Secret 类型
| 类型 | 说明 | 用途 |
|---|---|---|
| Opaque | 通用 Secret | 密码、Token |
| kubernetes.io/tls | TLS 证书 | HTTPS |
| kubernetes.io/dockerconfigjson | Docker 镜像仓库认证 | 拉取私有镜像 |
| kubernetes.io/service-account-token | ServiceAccount Token | API 访问 |
| kubernetes.io/basic-auth | 基本认证 | 用户名密码 |
创建 Secret
# Opaque Secret
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: default
type: Opaque
data:
username: YWRtaW4= # base64 编码的 "admin"
password: cEBzc3cwcmQ= # base64 编码的 "p@ssw0rd"
---
# 字符串数据 (自动 base64 编码)
apiVersion: v1
kind: Secret
metadata:
name: my-secret-string
namespace: default
type: Opaque
stringData:
username: admin
password: p@ssw0rd
# 命令行创建 Secret
kubectl create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password=p@ssw0rd
# 从文件创建 Secret
kubectl create secret generic my-secret \
--from-file=username.txt \
--from-file=password.txt
# 创建 TLS Secret
kubectl create secret tls my-tls \
--cert=tls.crt \
--key=tls.key
Pod 使用 Secret
# 环境变量方式
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: app
image: my-app:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password
---
# 挂载卷方式
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: my-secret
Secret 编码
# Base64 编码
echo -n "admin" | base64
# 输出: YWRtaW4=
# Base64 解码
echo "YWRtaW4=" | base64 -d
# 输出: admin
# 创建 Secret
kubectl create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password=p@ssw0rd \
--dry-run=client -o yaml
etcd 加密配置
# /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-secret>
- identity: {}
# 检查 etcd 加密状态
kubectl get secrets --all-namespaces -o json | kubectl neat
# 验证加密配置
kubectl get encryptionconfig -n kube-system
External Secrets Operator
# 安装 External Secrets Operator
# helm install external-secrets external-secrets/external-secrets
# SecretStore 配置
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
namespace: default
spec:
provider:
vault:
server: "http://vault:8200"
path: "secret"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes"
role: "my-role"
---
# ExternalSecret 配置
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-external-secret
namespace: default
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: my-secret
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: secret/my-app
property: username
- secretKey: password
remoteRef:
key: secret/my-app
property: password
HashiCorp Vault 集成
# Vault Agent 注入
apiVersion: v1
kind: Pod
metadata:
name: vault-agent-pod
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "my-role"
vault.hashicorp.com/agent-inject-secret-db-creds: "secret/data/my-app"
spec:
containers:
- name: app
image: my-app:latest
密钥轮换
# 使用外部密钥管理实现自动轮换
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: auto-rotating-secret
spec:
refreshInterval: 1h # 每小时检查更新
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: my-secret
data:
- secretKey: api-key
remoteRef:
key: secret/my-app
property: api-key
密钥管理最佳实践
1. 不要将 Secret 提交到代码仓库
- 使用 .gitignore
- 使用 Secret 管理工具
2. 启用 etcd 加密
- 配置 EncryptionConfiguration
- 定期轮换加密密钥
3. 使用外部密钥管理
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
4. 最小权限原则
- RBAC 限制 Secret 访问
- Pod 级别访问控制
5. 定期轮换密钥
- 自动轮换
- 监控过期时间
实践练习
练习 1:创建和使用 Secret
# 创建 Secret
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: default
type: Opaque
stringData:
username: admin
password: securepassword123
---
# Pod 使用 Secret
apiVersion: v1
kind: Pod
metadata:
name: db-client
spec:
containers:
- name: app
image: postgres:latest
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
# 应用配置
kubectl apply -f db-credentials.yaml
# 验证 Secret
kubectl get secret db-credentials -o yaml
练习 2:配置 etcd 加密
# 创建加密配置
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <生成的密钥>
- identity: {}
# 生成加密密钥
head -c 32 /dev/urandom | base64
# 配置 API Server
# 编辑 /etc/kubernetes/manifests/kube-apiserver.yaml
# 添加 --encryption-provider-config 参数
常见误解
1. Secret 是加密的
事实:Secret 默认只是 base64 编码,不是加密
误解:Secret 自动加密存储
解决:启用 etcd 加密或使用外部密钥管理
2. Secret 可以替代所有密钥管理
事实:Secret 是基本的密钥存储机制
误解:Secret 可以替代专业的密钥管理工具
解决:生产环境使用 Vault 等专业工具
小结
| 要点 | 说明 |
|---|---|
| Secret | 存储敏感信息的 Kubernetes 资源 |
| 编码方式 | Base64 编码 (非加密) |
| 安全增强 | etcd 加密、外部密钥管理 |
| 最佳实践 | 不提交代码仓库、启用加密、定期轮换 |
| 外部工具 | HashiCorp Vault、AWS Secrets Manager |
练习编辑器
bash
Loading...