16.7.5 Secrets与配置安全管理
Secrets与配置安全管理#
Kubernetes中配置与密钥管理的核心对象是ConfigMap与Secret。ConfigMap用于保存非敏感配置,Secret用于保存敏感信息(如密码、证书、令牌)。二者以键值对形式存储,可通过环境变量或挂载卷注入到Pod中。核心原则是“配置与镜像解耦”,确保镜像在不同环境复用。
原理与对象关系图#
Secret类型与创建方式(含命令解释)#
1) 通用Opaque(命令行创建)
# 创建通用Secret,--from-literal以明文键值生成
kubectl create secret generic app-db \
--from-literal=username=appuser \
--from-literal=password='S3cReT!' \
-n prod
# 预期:生成prod命名空间下的Secret/app-db
kubectl get secret app-db -n prod
2) TLS证书Secret(从文件创建)
# 证书文件放置示例路径
ls /etc/pki/tls/app.crt /etc/pki/tls/app.key
kubectl create secret tls app-tls \
--cert=/etc/pki/tls/app.crt \
--key=/etc/pki/tls/app.key \
-n prod
3) 镜像仓库认证(dockerconfigjson)
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=ci \
--docker-password='P@ssw0rd' \
--docker-email=ci@example.com \
-n prod
4) YAML声明式创建(stringData避免手工Base64)
# 文件:/opt/k8s/secret-app.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-api
namespace: prod
type: Opaque
stringData:
token: "t-123456"
endpoint: "https://api.example.com"
kubectl apply -f /opt/k8s/secret-app.yaml
挂载与使用模式(示例完整可执行)#
1) 以环境变量注入(适合少量配置)
# 文件:/opt/k8s/pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: env-demo
namespace: prod
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "env | grep APP_ && sleep 3600"]
env:
- name: APP_USER
valueFrom:
secretKeyRef:
name: app-db
key: username
- name: APP_PASS
valueFrom:
secretKeyRef:
name: app-db
key: password
kubectl apply -f /opt/k8s/pod-env.yaml
kubectl logs -n prod env-demo
# 预期:输出APP_USER/APP_PASS环境变量
2) 以卷挂载(推荐,适合证书/配置文件)
# 文件:/opt/k8s/pod-vol.yaml
apiVersion: v1
kind: Pod
metadata:
name: vol-demo
namespace: prod
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "ls /etc/secret && cat /etc/secret/username && sleep 3600"]
volumeMounts:
- name: secret-vol
mountPath: /etc/secret
readOnly: true
volumes:
- name: secret-vol
secret:
secretName: app-db
kubectl apply -f /opt/k8s/pod-vol.yaml
kubectl logs -n prod vol-demo
etcd静态加密(示例与命令解释)#
# 文件:/etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: MjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTA= # 32字节Base64
- identity: {}
# 1) 生成32字节密钥并Base64
head -c 32 /dev/urandom | base64
# 2) 修改apiserver静态Pod配置
# 文件:/etc/kubernetes/manifests/kube-apiserver.yaml
# 增加参数:
# --encryption-provider-config=/etc/kubernetes/encryption-config.yaml
# 并挂载配置文件
# 3) 验证:重新写入一个Secret以触发加密
kubectl delete secret app-db -n prod
kubectl create secret generic app-db --from-literal=username=appuser --from-literal=password='S3cReT!' -n prod
配置更新与发布策略(触发滚动更新示例)#
# 通过注解触发Deployment滚动重启
kubectl -n prod annotate deploy app \
kubernetes.io/change-cause="update secret $(date +%F_%T)"
# 或使用rollout restart
kubectl -n prod rollout restart deploy app
故障排查清单(含命令与解释)#
# 1) Secret不存在
kubectl -n prod get secret app-db
# 2) 挂载路径为空(检查Pod事件)
kubectl -n prod describe pod vol-demo | sed -n '/Events/,$p'
# 3) Base64解码异常(检查data字段)
kubectl -n prod get secret app-db -o yaml
# 4) RBAC无权限读取Secret
kubectl -n prod auth can-i get secret/app-db --as system:serviceaccount:prod:default
安全风险与防护要点#
- Secret默认Base64存储在etcd中,需启用etcd静态加密。
- 限制RBAC访问,仅授权必要的ServiceAccount。
- 禁止在镜像或代码中硬编码密码与令牌。
- 对敏感命名空间配置NetworkPolicy与最小访问原则。
练习#
1) 创建一个TLS Secret并挂载到Pod的/etc/tls目录,验证文件是否存在。
2) 将ConfigMap与Secret分别以环境变量注入同一Pod,比较两者的适用场景。
3) 启用etcd静态加密后,重新创建Secret并验证apiserver正常工作。
4) 使用kubectl auth can-i验证无权限账号无法读取Secret。