secret是唯一合规方式,因configmap、环境变量、镜像内嵌均等同明文泄露;环境变量会残留进程内存和/proc/environ,而secret挂载可设defaultmode:0400控制权限,且须rbac精确授权具体secret名称。

Secret 是唯一合规的保存方式,其他任何路径(包括 ConfigMap、环境变量硬编码、镜像内嵌)都等同于明文泄露。
为什么不能用环境变量注入 MONGO_PASSWORD
很多人直接在 Deployment 里写 env: - name: MONGO_PASSWORD value: "xxx",这看似“隐藏”,实则完全不安全:
• Base64 编码不是加密,kubectl get secret xxx -o yaml 一解就出明文
• CI/CD 日志、GitOps 同步记录、kubectl get deploy -o yaml 输出都会暴露密码
• RBAC 若配置宽松,普通开发也能读取整个命名空间的 Secret
必须用 Opaque 类型创建密码 Secret
MongoDB 连接凭据属于通用敏感字符串,只能用 Opaque 类型:
• 错误做法:kubectl create secret generic mongo-creds --from-file=password.txt(文件内容带换行会破坏 Base64)
• 正确做法:kubectl create secret generic mongo-creds --from-literal=username=admin --from-literal=password=MyS3cureP@ssw0rd
• 避免使用 docker-registry 或 service-account 类型——它们有固定 schema,MongoDB 不认
挂载比环境变量更安全,且必须设 defaultMode: 0400
环境变量会留在容器进程内存和 /proc/<pid>/environ</pid> 中,而 volume 挂载可控制权限:
• 必须在 volume 定义中显式设置 defaultMode: 0400,否则挂载后文件权限可能是 0644
• Pod spec 中要这样写:
volumeMounts:<br>- name: mongo-creds<br> mountPath: /etc/mongo/secret<br> readOnly: true<br>volumes:<br>- name: mongo-creds<br> secret:<br> secretName: mongo-creds<br> defaultMode: 0400
• 修改 Secret 后,Pod 不会自动重载,必须手动删除重建(Operator 管理的资源除外)
RBAC 必须精确到具体 Secret 名称,不能泛授权
默认 ServiceAccount 对 Secret 没读权限,报错 secrets "mongo-creds" is forbidden 就是没配 RBAC:
• 错误:给整个 namespace 所有 Secret 授权(resources: ["secrets"])
• 正确:只放行目标 Secret:
rules:<br>- apiGroups: [""]<br> resources: ["secrets"]<br> resourceNames: ["mongo-creds"]<br> verbs: ["get"]
• 注意命名空间必须严格匹配,跨 ns 访问需额外配置 ServiceAccount 绑定
真正容易被忽略的是:Secret 更新后,旧 Pod 里的挂载内容不会刷新;哪怕你用 Operator,也得确认它是否监听 Secret 变更并触发滚动更新——很多自定义 Operator 并不支持这个行为。











