MongoDB敏感信息必须用Secret管理,RBAC仅控制访问权限,volume挂载比环境变量更安全;密码不可明文写入Deployment,需分类型创建Secret,RBAC须精确到具体Secret名称,挂载时需设defaultMode: 0400并手动重启Pod生效。

直接说结论:MongoDB 的密码、密钥文件、TLS 证书等敏感信息,必须用 Secret 管理,且不能裸露在 Pod spec 或镜像中;RBAC 不是用来“保护 Secret 内容”的,而是控制“谁有权读取/修改它”;volume 挂载是比环境变量更安全的使用方式,尤其对密钥文件和证书。
为什么不能把 MongoDB 密码写进 Deployment YAML
有人图省事,在 Deployment 里直接写 env: - name: MONGO_PASSWORD value: "mysecret123" —— 这等于把密码明文塞进 etcd(Base64 编码 ≠ 加密),任何有 get secrets 权限的人都能 kubectl get secret xxx -o yaml 解出来。更糟的是,如果误配了 RBAC,连普通开发也能看到整个命名空间的 Secret。
真实风险场景包括:
- CI/CD 流水线日志打印出完整 Pod spec,含密码字段
- 运维误执行
kubectl get deploy -o wide后截图发群 - GitOps 工具(如 Argo CD)同步时,未过滤敏感字段导致配置泄露
创建 MongoDB 所需的 Secret 类型要分清
MongoDB 常见敏感项有三类,对应不同 type 和创建方式:
-
Opaque:存连接密码、SCRAM 认证凭据,用kubectl create secret generic mongo-creds --from-literal=username=admin --from-literal=password=xxx -
kubernetes.io/tls:存 TLS 证书和私钥,必须用--cert-file和--key-file参数,否则证书格式校验失败 -
Opaque(但内容是密钥文件):MongoDB 副本集节点间通信用的keyFile,需确保文件权限为400,且挂载后容器内路径不可写(避免被篡改)
注意:docker-registry 类型不适用 MongoDB 场景,别混用;service-account 类型是系统自建的,别手动覆盖。
RBAC 配置必须精确到命名空间 + Secret 名称
默认情况下,ServiceAccount(比如 default)对同命名空间的 Secret 没有读权限。如果你的 Pod 启动报错 error reading secret "mongo-creds": secrets "mongo-creds" is forbidden,就是 RBAC 没配。
最小权限配置示例(仅允许应用 Pod 读取指定 Secret):
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: mongo-prod name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["mongo-creds", "mongo-tls", "mongo-keyfile"] verbs: ["get"]
然后绑定到 Pod 使用的 ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: app-secret-reader namespace: mongo-prod subjects: - kind: ServiceAccount name: mongo-app-sa namespace: mongo-prod roleRef: kind: Role name: secret-reader apiGroup: rbac.authorization.k8s.io
关键点:resourceNames 必须显式列出,不能只写 resources: ["secrets"] —— 否则等于开放整个命名空间所有 Secret 的读取权。
用 volume 挂载 Secret 时要注意路径与权限
环境变量方式会把密码注入进程环境,可能被 ps aux 或调试工具捕获;而 volume 挂载更可控,尤其对 keyFile 这种必须严格权限的文件:
- 挂载
keyFile时,务必加defaultMode: 0400,否则容器内文件默认是0644,MongoDB 启动会拒绝加载 - 证书挂载路径建议固定为
/etc/mongo/tls/,并在容器启动命令中显式指定--tlsCertificateKeyFile /etc/mongo/tls/tls.pem - 不要把多个 Secret 挂到同一目录下,避免 key 冲突;可用
items字段重映射单个 key 到指定文件名
一个典型挂载片段:
volumeMounts:
- name: mongo-keyfile
mountPath: /etc/mongo/keyfile
readOnly: true
volumes:
- name: mongo-keyfile
secret:
secretName: mongo-keyfile
defaultMode: 0400最后提醒一句:Secret 更新后,volume 中的文件会自动更新(几秒内),但 MongoDB 进程不会自动 reload keyFile 或证书 —— 你得触发滚动更新或手动重启 Pod,这点容易被忽略。


















