必须使用 mongodb kubernetes operator(v1.25+)部署分片集群,因其动态管理mongos服务发现、副本集自动reconfig、csrs初始化及元数据同步;纯yaml无法响应事件,且需配置publishnotreadyaddresses: true、跨az反亲和及手动多集群故障转移。

直接用 Kubernetes Operator 部署 MongoDB 分片集群是目前最稳定、可维护性最强的方式;手动写 StatefulSet + Service + ConfigMap 组合容易漏掉分片路由(mongos)、配置服务器副本集(configsvr)和分片间通信的 TLS/网络策略,上线后极易出现 chunk 迁移卡住或 mongos 无法发现分片节点的问题。
必须用 MongoDB Kubernetes Operator,不能只靠原生 YAML
Operator 不只是封装了部署逻辑,它会动态管理:mongos 的服务发现、分片副本集成员变更时的自动 reconfig、配置服务器的 CSRS 模式初始化、以及分片添加/删除时的元数据同步。纯 YAML 部署无法响应这些事件,比如你手动扩缩一个分片的 Pod 数量,Operator 会触发 rs.add() 或 rs.remove(),而裸 YAML 不会。
- 必须安装
mongodb-kubernetes-operatorv1.25+(支持 MongoDB 6.0+ 和多集群分片) - CRD 必须包含
MongoDBShardedCluster资源类型,不是MongoDB(那是副本集) - Operator 命名空间需提前创建并打上
mongodb.com/operator: "true"标签 - 不支持 Helm chart 直接部署分片集群——官方 Helm chart 仅覆盖副本集和独立实例
mongos 服务必须启用 publishNotReadyAddresses: true
这是最容易被忽略的致命配置。默认情况下,Kubernetes 会在 mongos Pod 尚未完成与 Ops Manager/Cloud Manager 连接、或尚未加载完分片拓扑前,将其从 Service 的 Endpoints 中剔除。结果就是客户端连接 mongos 时偶发 Connection refused 或超时,但 Pod 日志看起来一切正常。
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
- 在
mongos对应的 Service 定义中显式设置:publishNotReadyAddresses: true - 该字段必须加在
spec下,不是metadata或status - Operator v1.23+ 可通过 CR 的
spec.mongos.serviceTemplate注入此字段,老版本需 patch Service - 不设此项,分片集群在滚动更新或故障恢复期间大概率出现短暂不可用
分片副本集必须跨节点部署,且禁用 podAntiAffinity 的 topologyKey="topology.kubernetes.io/zone"
分片节点(shard)本质是副本集,其高可用依赖多数派投票。如果所有副本都调度到同一可用区(AZ),该 AZ 故障即导致整个分片不可写。但 Kubernetes 默认的 podAntiAffinity 规则常误用 topologyKey: "topology.kubernetes.io/zone",而实际集群可能没正确标注节点 zone 标签,或用了自定义 label(如 failure-domain.beta.kubernetes.io/zone),导致反亲和失效甚至 Pod 卡在 Pending 状态。
- 检查节点是否真实带有
topology.kubernetes.io/zone标签:kubectl get nodes -o wide --show-labels | grep zone - 若无,改用
topologyKey: "failure-domain.beta.kubernetes.io/zone"(旧版 K8s)或统一补标签 - Operator CR 中配置分片时,必须显式声明
spec.shardTopology并指定antiAffinity策略 - 切勿依赖默认 antiAffinity —— Operator 默认不开启跨 AZ 调度
多集群分片要手动处理故障转移,Operator 不自动迁移
当你把分片分散在多个 Kubernetes 集群(比如 us-east、eu-west、ap-southeast),Operator 不会感知成员集群宕机并自动把分片迁走。它只会不断重试连接失败的集群,直到你人工干预。
- 第一步:将故障集群的分片副本数缩容为 0,命令类似:
kubectl scale statefulset <shard-name> --replicas=0 -n <ns></ns></shard-name> - 第二步:编辑
MongoDBShardedClusterCR,从spec.shards列表中移除对应分片条目 - 第三步:在健康集群中新增分片,并运行
sh.addShard()手动触发数据均衡(Operator 不自动调用) - 注意:
movePrimary操作期间禁止对未分片库执行写入,否则可能丢数据
真正麻烦的从来不是“怎么部署”,而是“怎么让分片之间持续可信通信”——这取决于你的网络插件是否支持跨集群 Pod CIDR 路由、TLS 证书是否覆盖所有 mongos 和分片的 DNS 名、以及 configsvr 副本集是否真的以 CSRS 模式启动(不是旧式的 SCCC)。这些细节不出现在任何一键脚本里,但每一条都会让集群在流量高峰时静默降级。










