两者定位差异
Secret 与 ConfigMap 的对象结构几乎一样:都是键值集合,都能以环境变量或卷的方式注入,都有约 1MiB 的大小上限。区别不在格式而在定位与安全语义——Secret 面向凭据,值以 base64 存储、配合静态加密和更严的 RBAC;ConfigMap 面向普通配置,值明文存放。选错容器会打乱权限模型,也会让非敏感配置背上不必要的管理成本。
维度对比
| 维度 | ConfigMap | Secret |
|---|---|---|
| 值存储形式 | 明文 | base64(编码,不是加密) |
| 静态加密 | 不适用 | 可配置 EncryptionConfiguration 与 KMS |
| RBAC 关注度 | 通常宽松 | 应单独收紧,读取即等于拿到凭据 |
| 注入方式 | env / envFrom / 卷 | env / envFrom / 卷,另可用于镜像拉取凭据 |
| 大小上限 | 约 1MiB | 约 1MiB |
| 典型内容 | 日志级别、配置文件、功能开关 | 数据库口令、API Key、证书、镜像仓库凭据 |
典型使用场景
- 应用配置:日志级别、超时、功能开关放 ConfigMap,调整时不动凭据相关的对象
- 凭据管理:数据库密码、第三方令牌放 Secret,并给它单独的 Role 授权名单
- 镜像拉取:私有仓库凭据只能放 Secret(dockerconfigjson 类型的固定结构)
- 证书与私钥:TLS 证书走 kubernetes.io/tls 类型的 Secret,便于 Ingress 直接引用
- 两者都不放:超大配置文件放独立卷或对象存储,需要频繁变更的配置交给配置中心或数据库
选用判断顺序
选用判断顺序
# 1. 泄露后是否造成权限或数据风险?是 -> Secret
# 2. 是否需要单独限制谁能读?是 -> Secret
# 3. 是否只是行为参数、泄露无实质影响? -> ConfigMap
# 4. 是否超过 1MiB 或需要秒级变更? -> 卷 / 对象存储 / 配置中心
# 5. 是否属于运行时状态(会话、队列游标)? -> 数据库,不要塞进配置对象分别收紧权限
分别收紧权限
kubectl get configmap app-config -n prod -o jsonpath='{.data}' # 明文,可直接读
kubectl auth can-i get secrets --as=system:serviceaccount:prod:app-sa -n prod # 定期复核谁能读 Secret
kubectl get role,rolebinding -n prod -o wide | grep -i secret # 找出被授予 secret 读取权的绑定Secret 只是「更克制地暴露」:同一命名空间里任何被授权读取 Secret 的身份都能拿到明文,base64 不提供任何保密性。真正提升安全水位的是静态加密、最小化授权与审计日志,三者缺一都会留下口子。
容器同时挂了 ConfigMap 与 Secret 时,配置项重名以挂载顺序靠后者为准,排障时容易误判来源;建议给凭据键加统一前缀,例如 DB_PASSWORD 只出现在 Secret、LOG_LEVEL 只出现在 ConfigMap。