ConfigMap 与 Secret
一个常见的问题:应用的配置信息应该放在哪里?
放在代码里?不利于环境差异化管理。 放在环境变量里?配置多的时候难以维护。 放在配置中心?增加了系统复杂度。
Kubernetes 的 ConfigMap 和 Secret 提供了原生的配置管理方案。
ConfigMap 是什么?
ConfigMap 是用于存储非敏感配置的 API 对象。它可以将配置数据与 Pod 分离,使配置可以独立于应用镜像进行管理。
ConfigMap 适用于存储:
- 环境变量
- 命令行参数
- 配置文件
- 域名列表
- 其他配置数据
创建 ConfigMap
YAML 方式创建
Secret 是什么?
Secret 是用于存储敏感数据的 API 对象,如密码、OAuth 令牌、SSH 密钥等。
虽然叫 Secret,但默认存储在 etcd 中的是 Base64 编码,不是加密的。如果需要真正的加密存储,需要配置 EncryptionConfiguration 或使用 Vault 等外部方案。
Secret 类型
创建 Secret
YAML 方式创建
stringData 字段在写入 etcd 时会被转换为 Base64 编码,读取时不会显示明文。如果使用 YAML 创建 Secret,请确保 Base64 编码的值不包含换行符。
使用 ConfigMap 和 Secret
挂载为环境变量
挂载为文件
对比:环境变量 vs 文件挂载
配置热更新
ConfigMap 热更新
当 ConfigMap 通过 Volume 挂载时,更新 ConfigMap 会自动同步到挂载的文件:
通过环境变量引用的 ConfigMap 值不会自动更新。如果需要热更新配置,建议使用 Volume 挂载方式,或者重启 Pod。
Secret 热更新
Secret 的热更新行为与 ConfigMap 相同:
更新策略
可以配置挂载时不自动更新:
Secret 加密
启用静态加密
启用加密
最佳实践
ConfigMap 最佳实践
- 按用途分离:不同用途的配置放在不同的 ConfigMap
- 命名规范:使用有意义的名称,如
app-frontend-config、app-backend-config - 版本控制:将 ConfigMap 的 YAML 文件纳入 Git 版本控制
Secret 最佳实践
- 不要提交明文 Secret:使用 sealed-secret、vault 等方案
- 限制 Secret 访问:使用 RBAC 控制谁可以读取 Secret
- 定期轮换:定期更换密钥和密码
镜像仓库凭证
常见问题
ConfigMap 挂载后文件为空
常见原因:
- ConfigMap 的
data字段为空 items指定的key不存在subPath指定的路径不存在
Secret 无法挂载
如果 Secret 存在但挂载失败,检查:
- Secret 类型是否正确
items中的key是否存在- Pod 是否有权限访问 Secret
环境变量注入时机
环境变量在容器启动时注入,不会动态更新。如果需要更新环境变量,需要重建 Pod:
延伸思考
ConfigMap 和 Secret 是 Kubernetes 配置管理的基石。它们让配置与代码分离,使同一套镜像可以用于不同环境(dev、staging、production)。
但它们也有局限性:
- 不支持配置验证:ConfigMap 的内容没有 schema 验证
- 不支持热更新(环境变量):只能通过重启或 Volume 挂载解决
- Secret 不加密:默认存储是 Base64 编码,不是真正的加密
对于更复杂的配置管理需求,可以考虑:
- Kustomize:管理多环境的配置差异
- Helm:管理复杂的应用配置
- External Secrets Operator:集成 AWS Secrets Manager、Vault 等外部密钥管理
延伸阅读
- Volume 与 PVC/PV:持久化存储管理
- Kubernetes 安全:Secret 访问控制和加密
- Deployment 与 ReplicaSet:如何结合 ConfigMap 使用