StatefulSet是唯一可行控制器,因Deployment会导致数据丢失、节点无法识别、选举失败或脑裂;MongoDB副本集依赖稳定网络标识、独立存储绑定和有序启停,而这三者正是StatefulSet的核心设计目标。

StatefulSet 是唯一可行的控制器,Deployment 会导致数据丢失、节点无法识别彼此、选举失败甚至脑裂。MongoDB 副本集对网络标识、存储绑定和启动顺序有硬性要求,而这些恰恰是 StatefulSet 的设计目标。
为什么不能用 Deployment 部署 MongoDB 副本集
Deployment 生成的 Pod 名称随机、IP 不固定、重启后 PVC 可能被错误复用——这直接破坏 MongoDB 副本集的三个前提:
-
rs.add("mongo-1.mongo-svc.default.svc.cluster.local:27017")这类初始化命令依赖稳定 DNS 名,Deployment 无法提供mongo-1这样的确定性主机名 - 副本集成员通过
_id和host字段注册自身,Pod 重建后若挂载了别人的 PVC,mongod启动会因 oplog 冲突或WiredTiger.wt文件锁报错退出 - 滚动更新时多个 Pod 并发启动,可能同时尝试成为 Primary,触发无效选举,日志里反复出现
NotQuorumException或Node is not in primary state
Headless Service 必须显式配置 serviceName
StatefulSet 的 serviceName 字段必须指向一个 Headless Service(即 clusterIP: None),否则 DNS 解析不会生成 mongo-0.mongo-svc.default.svc.cluster.local 这类记录。
- Service 名字要和 StatefulSet 的
serviceName字段严格一致,比如都叫mongo-svc - Service 的
selector必须匹配 StatefulSet 模板里的labels,例如app: mongo - 别漏掉
publishNotReadyAddresses: true,否则 Pod 在Running但未就绪时,DNS 就查不到地址,导致初始化阶段成员互相发现失败
volumeClaimTemplates 必须用 ReadWriteOnce 且不可共享
MongoDB 不支持多实例并发写入同一份数据目录,NFS 等共享存储必须配成单客户端独占模式,否则 WiredTiger 会因文件锁异常崩溃。
-
accessModes: ["ReadWriteOnce"]是底线,哪怕底层是 NFS,也要确保每个 PVC 绑定到独立子目录(如/data/mongo/0、/data/mongo/1) - 不要在
volumeMounts中挂载/data/db以外的路径做数据盘,mongod不识别,也不会自动初始化 - 如果用云厂商存储(如 AWS EBS、Azure Disk),确认 StorageClass 的
reclaimPolicy是Retain,避免误删 PVC 导致 PV 被自动回收
副本集初始化必须由 InitContainer 或首 Pod 主动触发
StatefulSet 保证顺序启动(0→1→2),但 MongoDB 不会自动组成副本集——你得让 mongo-0 先起来并执行 rs.initiate(),再让 mongo-1、mongo-2 依次 rs.add()。
- 推荐用 InitContainer 检查
mongo-0.mongo-svc是否可连通,再用主容器的 entrypoint 脚本判断自己是不是 index 0:如果是,执行mongosh --eval "rs.initiate(...)"; sleep 10 - 所有 Pod 必须使用相同 keyfile(通过 Secret 挂载),否则
Unauthorized错误会卡在STARTUP2状态 - 别依赖
readinessProbe做健康检查:副本集刚启动时,Secondary 还没同步完,db.runCommand({ping:1})成功但rs.status().members[n].stateStr !== "PRIMARY",probe 失败会反复重启
最易被忽略的是 oplog 大小和 PVC 容量不匹配:默认 oplog 占磁盘 5%,但 PVC 如果只设 1Gi,oplog 实际只有 50Mi,高峰写入很快填满,导致 Secondary 同步延迟飙升甚至中断。上线前务必用 db.getReplicationInfo() 核对,并在 StatefulSet 的 resources.requests.storage 中留足余量。











