16.9.7 配置与密钥管理最佳实践

在生产环境中,配置与密钥管理应实现“可追溯、可审计、可回滚、最小暴露”。推荐将配置与代码分离,使用 ConfigMap 管理非敏感配置,使用 Secret 管理敏感信息,严禁将密钥写入镜像、源码仓库或明文环境变量文件。

原理草图(配置/密钥生命周期与访问路径):

文章图片

配置管理实践要点与示例(含命令解释):
1) 统一命名与分层组织
- 命名规则:<应用>-<环境>-<用途>,如 order-prod-config
- 分层目录:configs/<env>/<app>/

2) ConfigMap 创建与挂载示例
- 准备配置文件 /opt/k8s/configs/order-prod/app.yaml

# /opt/k8s/configs/order-prod/app.yaml
server:
  port: 8080
feature:
  enableCart: true
  • 创建 ConfigMap:
# 使用文件创建 ConfigMap
kubectl -n prod create configmap order-prod-config \
  --from-file=app.yaml=/opt/k8s/configs/order-prod/app.yaml

# 查看 ConfigMap 内容
kubectl -n prod get configmap order-prod-config -o yaml
  • Pod 挂载 ConfigMap:
# /opt/k8s/manifests/order-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order
  namespace: prod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: order
  template:
    metadata:
      labels:
        app: order
    spec:
      containers:
      - name: order
        image: registry.example.com/order:v1.2.0
        volumeMounts:
        - name: config-vol
          mountPath: /etc/order/app.yaml
          subPath: app.yaml
      volumes:
      - name: config-vol
        configMap:
          name: order-prod-config
  • 应用部署与验证:
kubectl apply -f /opt/k8s/manifests/order-deploy.yaml
kubectl -n prod exec deploy/order -- cat /etc/order/app.yaml
# 预期输出:app.yaml 内容

配置变更与回滚示例:

# 变更配置(替换文件后应用)
kubectl -n prod create configmap order-prod-config \
  --from-file=app.yaml=/opt/k8s/configs/order-prod/app.yaml \
  -o yaml --dry-run=client | kubectl apply -f -

# 滚动更新触发(可用 annotation 强制滚动)
kubectl -n prod rollout restart deploy/order

# 查看滚动状态
kubectl -n prod rollout status deploy/order

# 回滚示例
kubectl -n prod rollout undo deploy/order

密钥管理实践要点与示例:
1) 使用 Secret 管理敏感数据,避免明文入库
- 创建 Secret(示例为数据库账号):

kubectl -n prod create secret generic order-db-secret \
  --from-literal=username=order_user \
  --from-literal=password='S3cureP@ssw0rd'

kubectl -n prod get secret order-db-secret -o yaml
# data 字段为 base64,不是加密,需结合 KMS/Encryption at Rest

2) Secret 挂载为文件,避免环境变量泄露

# /opt/k8s/manifests/order-secret.yaml(片段)
      containers:
      - name: order
        image: registry.example.com/order:v1.2.0
        volumeMounts:
        - name: secret-vol
          mountPath: /etc/order/secret
          readOnly: true
      volumes:
      - name: secret-vol
        secret:
          secretName: order-db-secret
  • 应用读取示例:
kubectl -n prod exec deploy/order -- ls -l /etc/order/secret
kubectl -n prod exec deploy/order -- cat /etc/order/secret/username

3) 启用静态加密(Encryption at Rest)示例
- /etc/kubernetes/encryption-config.yaml

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: 9xYf3O7u4xV1mH6p5s8aQ3bD2c1ZxYf3
      - identity: {}
  • kube-apiserver 启动参数(示意):
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
  • 验证:重新写入 Secret 后观察 etcd 中数据不再明文(需有 etcd 访问权限)。

配置分发与动态配置建议:
- 高频变更配置使用配置中心(Nacos/Consul)
- 应用启动阶段进行配置校验失败即退出(触发回滚)
- 模板化与参数化,支持多环境一致部署

示例:启动前校验(容器启动脚本)

# /opt/k8s/scripts/entrypoint.sh
set -e
python /app/config_check.py /etc/order/app.yaml
exec /app/start.sh

安全与合规建议:
- 建立配置与密钥分类分级制度
- 对 CI/CD 变量进行权限隔离与环境保护
- 使用专用命名空间存放系统级配置
- Secret 禁止跨命名空间共享
- 变更需记录责任人与审批链路

常见排错清单(含命令与解释):
1) Pod 未加载最新 ConfigMap

kubectl -n prod describe pod <pod-name> | grep -A3 ConfigMap
# 检查是否正确引用 ConfigMap
kubectl -n prod rollout restart deploy/order

2) Secret 挂载为空或权限问题

kubectl -n prod describe pod <pod-name> | grep -A5 secret
# 查看挂载事件与错误
kubectl -n prod get secret order-db-secret -o yaml

3) 配置变更后应用未生效

# 检查容器内文件是否变化
kubectl -n prod exec <pod-name> -- md5sum /etc/order/app.yaml
# 若未变化,检查是否使用了 subPath(subPath 不自动更新)

4) RBAC 拒绝访问

kubectl -n prod auth can-i get secret/order-db-secret --as=system:serviceaccount:prod:order-sa
# 根据结果调整 Role/RoleBinding

练习与实操任务:
1) 创建 order-prod-config 并将其挂载到 /etc/order/app.yaml,验证内容可读。
2) 使用 kubectl rollout restart 触发滚动更新,观察 Pod 更新过程。
3) 创建 order-db-secret 并挂载为文件,应用读取 usernamepassword
4) 使用 kubectl auth can-i 验证仅允许 order-sa 访问 Secret。
5) 通过修改 ConfigMap 并回滚 Deployment,验证回滚效果。