ConfigMap 与 Secret
把配置和敏感信息从镜像中解耦出来。
ConfigMap 用于普通配置,Secret 用于敏感信息(密码、证书)。它们帮助保持镜像不可变,同时让配置在不同环境之间可控、可审计。
这篇快速上手补充了创建方式、环境变量与文件挂载、滚动更新触发以及安全实践。
适用场景
- 应用配置文件、开关、日志级别等非敏感参数。
- 数据库密码、API Token、TLS 证书等敏感信息。
为什么使用 ConfigMap 与 Secret
- 将配置与镜像解耦,避免重复构建。
- 便于在不同环境中切换参数。
- 支持凭据轮换与最小权限访问。
创建 ConfigMap 与 Secret
可以直接用命令创建:
kubectl create configmap app-config --from-literal=LOG_LEVEL=info
kubectl create secret generic db-secret --from-literal=DB_PASSWORD='changeme'
对应的 YAML:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
DB_PASSWORD: "changeme"
作为环境变量注入
全量导入:
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-secret
或只映射指定键:
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
以文件挂载
更适合配置文件或证书:
volumes:
- name: config
configMap:
name: app-config
- name: secret
secret:
secretName: db-secret
volumeMounts:
- name: config
mountPath: /etc/app/config
readOnly: true
- name: secret
mountPath: /etc/app/secret
readOnly: true
变更触发滚动更新
ConfigMap/Secret 变化不会自动重启 Pod,常见做法是在 Deployment 中加 checksum 注解:
metadata:
annotations:
checksum/config: "{{ .Values.configChecksum }}"
不用 Helm 时可手动滚动:
kubectl rollout restart deployment/my-app
命名空间与范围
ConfigMap/Secret 是命名空间级资源,Pod 与配置必须在同一命名空间。跨命名空间引用默认不允许。
安全建议
- Secret 只是 base64 编码,默认不加密,应开启 API Server 的 at-rest 加密。
- 用 RBAC 限制读取权限,避免无关 Pod 挂载。
- 生产环境可使用 Vault 或云 KMS 管理密钥。
- 不要把 Secret 提交到 git。
变更触发滚动更新
ConfigMap/Secret 变化不会自动重启 Pod,常见做法是在 Deployment 中加 checksum 注解:
metadata:
annotations:
checksum/config: "{{ .Values.configChecksum }}"
不用 Helm 时可手动滚动:
kubectl rollout restart deployment/my-app
通过文件创建
配置文件或证书可以直接从文件创建:
kubectl create configmap app-config --from-file=app.yaml=./app.yaml
kubectl create secret generic tls-secret --from-file=tls.crt=./tls.crt --from-file=tls.key=./tls.key
目录场景:
kubectl create configmap app-config --from-file=./config-dir
示例:应用 Deployment
下面是一个最小示例,演示 env 和文件挂载并用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 2
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: app
image: nginx:1.27
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-secret
volumeMounts:
- name: config
mountPath: /etc/app/config
readOnly: true
- name: secret
mountPath: /etc/app/secret
readOnly: true
volumes:
- name: config
configMap:
name: app-config
- name: secret
secret:
secretName: db-secret
排查思路
查看 Pod 是否加载正确:
kubectl describe pod <pod-name>
查看配置内容:
kubectl get configmap app-config -o yaml
kubectl get secret db-secret -o yaml
也可以 exec 进入 Pod 查看挂载文件:
kubectl exec -it <pod-name> -- ls -l /etc/app/config
kubectl exec -it <pod-name> -- ls -l /etc/app/secret
如果环境变量读取异常,检查 key 名称及命名空间是否一致。
大小与拆分策略
ConfigMap 有大小限制,建议把大文件拆分成多个资源,或放到对象存储。Secret 也有体积限制,证书和密钥建议分开管理,便于轮换。
常见坑点
- ConfigMap 体积上限约 1MiB,避免塞入大文件。
- 以 env 注入的 Secret 只在 Pod 启动时读取。
- 多容器场景下要保持名称一致。
不要把 ConfigMap 当数据存储使用。
配置变更与应用加载
ConfigMap 挂载为文件时,Kubernetes 会更新文件内容,但应用不一定自动重载。建议确认应用是否支持 reload,必要时通过滚动更新或热加载机制触发刷新。
轮换与生命周期
Secret 需要定期轮换。如果是 env 注入,必须重启 Pod;文件挂载虽会更新,但多数应用仍需要 reload 信号。
可以制定版本化策略,发布新 Secret 后保留旧版本一段时间再淘汰。
权限与审计
只给需要的 ServiceAccount 读取权限,避免全命名空间可见。对敏感配置建议配合审计日志或 GitOps 流程,保证变更可追溯。
配置拆分与命名
建议按应用拆分 ConfigMap/Secret,并使用统一的命名规则。这样在排错或回滚时更容易定位对应资源,减少误操作。
同时建议在 README 或运维文档中记录配置默认值与覆盖方式,避免误修改导致线上故障。
实操要点
- 先做快速盘点:
kubectl get nodes、kubectl get pods -A、kubectl get events -A。 - 对比“期望状态”和“实际状态”,
kubectl describe往往能解释漂移或失败原因。 - 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。
快速检查清单
- 资源定义与业务意图一致。
- Namespace、权限、镜像与环境匹配。
- 上线前具备健康探针与可观测日志。