在 Kubernetes 上跑 MongoDB,真正拉开差距的通常不是"能不能部署"------三个主流开源方案都能把 3 节点 ReplicaSet 跑起来。差距在后面:
- 安装过程是不是顺手,还是要先踩一圈坑?
- 删除 Primary Pod 之后,系统能不能自己恢复?
- 到了 Day-2 运维(扩缩容、重启、切主),体验差多少?
这篇文章基于一组统一环境下的实测,比较三条开源路径:MongoDB Community Operator 、Percona Operator for MongoDB 和 KubeBlocks MongoDB。不比数据库内核性能,不编造未验证的 benchmark,只看安装、交付、failover 和运维体验。
先给结论:三者都能完成基础交付;但如果你关心的不只是"跑起来",而是团队级的复制性、运维可追踪性和平台化方向,KubeBlocks 值得优先评估。
测试环境与统一边界
为保证可比性,三个方案使用同一套测试环境和资源规格:
- Kubernetes 环境:Azure AKS v1.32.6
- 目标拓扑:3 节点 MongoDB ReplicaSet
- 统一资源规格 :CPU
500m / 1,Memory1Gi / 2Gi,PVC20Gi
集群节点规格
| Node | CPU | Memory |
|---|---|---|
aks-agentpool-27716930-vmss000000 |
2 vCPU | 8GB |
aks-str8v3-36690718-vmss00001k |
8 vCPU | 32GB |
aks-str8v3-36690718-vmss00001m |
8 vCPU | 32GB |
aks-str8v3-36690718-vmss00001t |
8 vCPU | 32GB |
| 简单说就是 1 个 2C 节点 + 3 个 8C 节点,跑 3 副本 MongoDB 绰绰有余。 |
Failover 判定标准
本文只测 delete-primary-pod 场景。判定是否成功,同时看三个条件------不是只看 Pod Running 就算完事:
- 删除 Primary 后是否出现新 Primary;
- 被删除 Pod 是否重建成功;
- 副本集是否恢复到健康状态(1 Primary + 2 Secondary)。
三种 Operator 的版本信息
| 方案 | Operator / Chart | 版本 | 核心管理对象 |
|---|---|---|---|
| MongoDB Community Operator | mongodb/mongodb-kubernetes |
MCK v1.8.0 |
MongoDBCommunity |
| Percona Operator for MongoDB | percona/psmdb-operator / percona/psmdb-db |
1.22.0 / psmdb-db-1.22.2 |
PerconaServerMongoDB |
| KubeBlocks MongoDB | kubeblocks/kubeblocks + MongoDB add-on |
kubeblocks-1.0.3-beta.5 + mongodb-1.0.3 |
Cluster |
总览:先看结果
| 方案 | 安装路径 | Operator 安装到集群 Ready | Failover 恢复 | 3 节点副本集 | 总体判断 |
|---|---|---|---|---|---|
| Community Operator | Helm + Secret + MongoDBCommunity CR |
~15 分钟 | ~2 分 57 秒 | ✅ | 原生基线清晰,复制门槛不低 |
| Percona Operator | Helm + PerconaServerMongoDB CR |
~8 分钟 | ~1 分 53 秒 | ✅ | 能力完整,适合 MongoDB 专项团队 |
| KubeBlocks | Helm + Cluster CR |
~5 分钟 | ~54 秒 | ✅ | 最接近平台化交付路线 |
三者都通过了测试。但正如后文会展开的,差距不在 Day-1 部署,而在 Day-2 运维和长期维护成本。
"Operator 安装到集群 Ready" 指从
helm installOperator 到 CR 状态 Ready/Running 且rs.status()确认副本集健康的全链路时间。三组测试在同一集群、相同网络条件下顺序执行,镜像均为首次拉取。
一、MongoDB Community Operator
Community Operator 的标签是"原生、直接、贴近 MongoDB 官方 CR 模型"。 好处是心智模型清晰,不好的地方是------它对字段细节很挑剔。
先说一个容易踩坑的背景:MongoDB 官方已经把企业版和社区版 Operator 合并成了一个项目 mongodb-kubernetes(MCK) 。这意味着你 helm install 拉下来的是一个同时服务企业版和社区版的 Operator,里面包含企业版 CRD(如 MongoDBOpsManager、MongoDB)和社区版 CRD(MongoDBCommunity)。对只想用社区版的团队来说,这不算致命问题,但确实会让新手在读文档和排查 CRD 时多绕弯------你需要自己在企业版和社区版的概念之间做区分,官方文档也经常混在一起讲。这也是 Community Operator 安装耗时偏长(~15 分钟)的原因之一:合并后的 Operator 镜像更大,CRD 更多。
安装与创建集群
通过 Helm 安装 Operator:
bash
kubectl create namespace mongodb
helm repo add mongodb https://mongodb.github.io/helm-charts
helm repo update
helm install mongodb-kubernetes mongodb/mongodb-kubernetes -n mongodb
创建集群前,需要先准备一个用户密码 Secret------这是 Community Operator 的一个小门槛:集群 CR 本身不能独立工作,需要额外的 Secret 资源配合。
yaml
apiVersion: v1
kind: Secret
metadata:
name: my-user-password
namespace: mongodb
type: Opaque
stringData:
password: mypassword123
然后提交集群 CR:
yaml
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
name: mongodb-cluster
namespace: mongodb
spec:
members: 3
type: ReplicaSet
version: "7.0.4"
security:
authentication:
modes: ["SCRAM"]
users:
- name: my-user
db: admin
passwordSecretRef:
name: my-user-password
roles:
- name: clusterAdmin
db: admin
- name: userAdminAnyDatabase
db: admin
scramCredentialsSecretName: my-user-scram
statefulSet:
spec:
template:
spec:
containers: []
volumeClaimTemplates:
- metadata:
name: data-volume
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
- metadata:
name: logs-volume
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
additionalMongodConfig: {}
注意它要求同时声明 data-volume 和 logs-volume 两个 PVC 模板,所以 3 节点会产生 6 个 PVC。
集群状态验证
bash
kubectl -n mongodb get pods
kubectl -n mongodb get mongodbcommunity
kubectl -n mongodb get pvc
| 检查项 | 实际结果 |
|---|---|
| Operator | mongodb-kubernetes-operator Running |
| Cluster CR | MongoDBCommunity/mongodb-cluster 创建成功 |
| MongoDB Pods | 3 个 Pod Running |
| PVC | 6 个 PVC Bound |
进入 Pod 确认副本集内部状态:
bash
kubectl -n mongodb exec -it mongodb-cluster-0 -c mongod -- mongosh \
-u my-user -p mypassword123 --authenticationDatabase admin \
--quiet --eval 'rs.status().members.map(m => ({name:m.name,stateStr:m.stateStr}))'
结果确认 3 个成员全部健康,mongodb-cluster-0 为 PRIMARY。从 Helm 安装到集群就绪,端到端耗时约 15 分钟。
Failover 测试
bash
# 删除 Primary Pod
kubectl -n mongodb delete pod mongodb-cluster-0
# 等待 Pod 重建
kubectl -n mongodb wait --for=condition=Ready pod/mongodb-cluster-0 --timeout=300s
恢复耗时约 2 分 57 秒。再次检查副本集:
| 检查项 | Failover 后结果 |
|---|---|
| 新 Primary | mongodb-cluster-1 |
| 被删除 Pod | mongodb-cluster-0 重建为 SECONDARY |
| 最终拓扑 | 1 Primary + 2 Secondary,全部 health=1 |
顺便提一句:mongosh 在容器里会打一个 EACCES 告警,看着像出了问题,其实只是本地目录权限告警,不影响副本集状态。
小结
Community Operator 最大的特点不是"不能用",而是"需要你对 MongoDB 原生字段有足够了解"。passwordSecretRef、scramCredentialsSecretName、containers: [] 这些写法,对 MongoDB 老手不算问题,但对想快速复制部署的团队来说,门槛实实在在。
二、Percona Operator for MongoDB
Percona 走的是另一条路:MongoDB 专项能力做得很全,sharding、备份、加密、监控都有覆盖。代价是 CR 结构相对复杂。
安装与创建集群
bash
kubectl create namespace percona-mongodb
helm repo add percona https://percona.github.io/percona-helm-charts/
helm repo update
helm install psmdb-operator percona/psmdb-operator --namespace percona-mongodb
然后提交集群 CR。这个 CR 内容比较长,这里只列核心配置:
yaml
apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDB
metadata:
name: cluster1-psmdb-db
namespace: percona-mongodb
spec:
crVersion: 1.22.0
image: "percona/percona-server-mongodb:8.0.19-7"
updateStrategy: SmartUpdate
pmm:
enabled: false
image: "percona/pmm-client:3.6.0"
serverHost: monitoring-service
replsets:
- name: rs0
size: 3
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
volumeSpec:
persistentVolumeClaim:
resources:
requests:
storage: 20Gi
affinity:
antiAffinityTopologyKey: kubernetes.io/hostname
podDisruptionBudget:
maxUnavailable: 1
backup:
enabled: true
image: "percona/percona-backup-mongodb:2.12.0"
logcollector:
enabled: true
image: "percona/fluentbit:4.0.1-2"
resources:
requests:
cpu: 200m
memory: 100M
Percona 的 CR 还包含 PMM 监控、日志采集、升级策略等大量可配字段------能力全面,但首次上手确实要读不少文档。
集群状态验证
bash
kubectl -n percona-mongodb get pods
kubectl -n percona-mongodb get psmdb
kubectl -n percona-mongodb get pvc
| 检查项 | 实际结果 |
|---|---|
| Operator | 成功 |
| Cluster CR | PerconaServerMongoDB/cluster1-psmdb-db 创建成功 |
| 3 节点副本集 | Running |
| PVC | 全部 Bound |
有一点值得说明:Percona 的凭据与角色权限模型跟 Community 不同。直接用低权限用户跑 rs.status() 不一定行得通,实际验证更多依赖 psmdb CR 状态和 Pod 健康度。端到端耗时约 8 分钟。
Failover 测试
bash
kubectl -n percona-mongodb delete pod <primary-pod-name>
kubectl -n percona-mongodb wait --for=condition=Ready pod/<primary-pod-name> --timeout=300s
kubectl -n percona-mongodb get psmdb
Failover 恢复耗时约 1 分 53 秒,角色切换完成,集群恢复健康。
小结
Percona 的定位很明确:给 MongoDB 专项团队用的全能型 Operator。如果你需要 sharding、备份/PITR、加密、PMM 监控这些能力,Percona 的覆盖面确实比 Community 强很多。只是它的学习曲线相对陡峭------Helm values 结构跟 chart 版本绑定较紧,CR 字段也比较多。
三、KubeBlocks
如果说前两个方案更像"MongoDB 专属管家",KubeBlocks 的思路完全不同------它是一个数据库平台,MongoDB 是它支持的 30 多种引擎之一。
安装与创建集群
先装 KubeBlocks 核心和 MongoDB add-on:
bash
helm repo add kubeblocks https://apecloud.github.io/helm-charts
helm install kubeblocks kubeblocks/kubeblocks \
--namespace kb-system --create-namespace
kbcli addon enable mongodb
本次测试使用 KubeBlocks 1.0.3-beta.5 + MongoDB addon 1.0.3。
创建集群的 CR 非常简洁:
yaml
apiVersion: apps.kubeblocks.io/v1
kind: Cluster
metadata:
name: kb-mongodb-test
namespace: demo
spec:
clusterDef: mongodb
topology: replicaset
terminationPolicy: Delete
componentSpecs:
- name: mongodb
serviceVersion: "8.0.17"
replicas: 3
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "1"
memory: "2Gi"
volumeClaimTemplates:
- name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "20Gi"
跟前两者对比:不需要额外 Secret,不需要处理 sharding 开关,clusterDef: mongodb + topology: replicaset + replicas: 3 就把意图说清楚了。密码自动生成在 Secret 里。
集群状态验证
bash
kubectl -n demo get cluster
kubectl -n demo get pods --show-labels
kubectl -n demo get pvc
| 检查项 | 实际结果 |
|---|---|
| Cluster | kb-mongodb-test Ready |
| 3 节点副本集 | Running |
| PVC | Bound |
| Pod 角色 | 标签直接显示 kubeblocks.io/role=primary/secondary |
最后一行是 KubeBlocks 独有的:你不需要进 Pod 执行 rs.status() 就能看出谁是 Primary 。kubectl get pods --show-labels 或者 kubectl get pods -L kubeblocks.io/role 直接就能看到。
当然,如果想二次确认,也可以从 MongoDB 内部验证:
bash
kubectl -n demo exec -it kb-mongodb-test-mongodb-0 -c mongodb -- mongosh \
--quiet --eval 'rs.status().members.map(m => ({name:m.name,stateStr:m.stateStr}))'
端到端耗时约 5 分钟。
Failover 测试
bash
kubectl -n demo delete pod kb-mongodb-test-mongodb-0
kubectl -n demo wait --for=condition=Ready pod/kb-mongodb-test-mongodb-0 --timeout=300s
Failover 恢复耗时约 54 秒。Pod 重建成功,新 Primary 产生,副本集恢复为 1 Primary + 2 Secondary。
小结
从 Day-1 体验看,KubeBlocks 的安装和创建集群体验是三者中最顺手的。但真正让它跟另外两个拉开差距的,不在 Day-1,而在后面的 Day-2 运维------这也是下文要展开的重点。
四、测试结果对比
三组测试跑完,先把关键数据放到一起。
安装与交付
| 维度 | Community | Percona | KubeBlocks |
|---|---|---|---|
| Operator 安装到集群 Ready | ~15 分钟 | ~8 分钟 | ~5 分钟 |
| 创建集群所需资源 | Secret + MongoDBCommunity CR |
PerconaServerMongoDB CR |
Cluster CR |
| 3 节点 ReplicaSet | ✅ | ✅ | ✅ |
| PVC | 6 个(data + logs) | 3 个 | 3 个 |
为了排除 Operator 安装阶段的干扰,我们在同一环境下做了一轮重测,只计"创建集群资源 → 集群 Ready"这一段(Community 和 Percona 均在 Operator 就绪后开始计时):
| 方案 | 计时起点 | 集群 Ready 耗时 | 相对倍数 |
|---|---|---|---|
| KubeBlocks | kubectl apply 创建 Cluster CR |
51.0 秒 | 1x |
| Community | kubectl apply 创建 MongoDBCommunity CR |
190.4 秒 | 3.7x |
| Percona | helm install 安装 psmdb-db chart |
202.0 秒 | 4.0x |
KubeBlocks 的集群创建速度大约是 Community 的 3.7 倍 、Percona 的 4 倍。差距主要来自三个架构层面的差异:
1)InstanceSet 并行建 Pod vs StatefulSet 串行建 Pod。 Community 和 Percona 都用原生 StatefulSet,行为是严格串行的:pod-0 Ready → 才创建 pod-1 → pod-1 Ready → 才创建 pod-2。三个 Pod 的启动时间是累加关系。KubeBlocks 的 InstanceSet 三个 Pod 同时创建,总耗时只取决于最慢的那个 Pod------单这一项就把 ~160 秒的串行等待压缩到 ~30 秒。
2)状态收敛机制不同。 Community Operator 不直接操作 mongod,而是把配置写入 Secret,由 Pod 内的 MongoDB Agent 轮询检测变更后执行 rs.initiate() 并上报状态,这个轮询循环引入了明显延迟。Percona 由 controller 直接管理副本集初始化,没有 Agent 轮询开销,但仍受串行建 Pod 拖累。KubeBlocks 的 roleProbe 在 Pod 就绪后直接探测 MongoDB 角色并写入 Pod 标签,Operator watch 标签后快速收敛 Cluster 状态。
Failover
| 维度 | Community | Percona | KubeBlocks |
|---|---|---|---|
| 恢复耗时 | ~2 分 57 秒 | ~1 分 53 秒 | ~54 秒 |
| 测试动作 | 删除 Primary Pod | 删除 Primary Pod | 删除 Primary Pod |
| 观察方式 | rs.status() + Pod Ready |
CR 状态 + Pod 恢复 | rs.status() + Cluster 状态 + Pod 标签 |
| 结果 | ✅ | ✅ | ✅(复测成功) |
| 最终拓扑 | 1P + 2S | 恢复健康 | 1P + 2S |
工程体验
| 方案 | 一句话概括 |
|---|---|
| Community | 官方原生基线,适合建立 MongoDB CR 认知,但复制到团队有门槛 |
| Percona | MongoDB 专项能力最全,但学习曲线陡峭 |
| KubeBlocks | 创建简洁、角色可观测、运维可追踪,最接近平台化交付 |
到这里,Day-1 的对比基本结束。三者都能把 MongoDB 跑起来,failover 也都能过。 但选型决策不会只停留在"能不能装"------真正的分水岭在 Day-2:集群跑起来之后,扩容怎么做?重启怎么做?切主怎么做?出了问题怎么定位?
五、从 Day-1 到 Day-2:三种 Operator 的能力全景对比
前面的实测证明三者都能"跑起来"。这一节我们跳出安装和 failover,从架构设计、生命周期管理、高可用、备份、安全、监控等维度做一次全面对比------看看谁真正为 Day-2 做了准备。
架构对比
| 维度 | Community Operator | Percona Operator | KubeBlocks |
|---|---|---|---|
| 维护方 | MongoDB Inc. | Percona | ApeCloud |
| 开源协议 | Apache 2.0 | Apache 2.0 | AGPL 3.0 |
| 核心定位 | MongoDB 社区版 K8s 交付 | 企业级 MongoDB on K8s | 统一数据库平台 |
| CRD | MongoDBCommunity |
PerconaServerMongoDB |
Cluster + OpsRequest |
| 底层工作负载 | StatefulSet | StatefulSet | InstanceSet(自研) |
| 是否只管 MongoDB | 是 | 是 | 否,支持 30+ 引擎 |
值得展开说一下 InstanceSet。KubeBlocks 没有直接用原生 StatefulSet,而是自研了一个叫 InstanceSet 的工作负载控制器。这不是为了造轮子------StatefulSet 在数据库场景下有几个实际痛点:
- 不知道哪个 Pod 是 Primary,缩容时可能误删主节点;
- 滚动更新时没有主从顺序概念;
- 不支持同一组 Pod 有不同的资源配置。
InstanceSet 内置了 roleProbe (定期探测每个 Pod 的 MongoDB 角色),把角色信息写入 Pod 标签。这意味着缩容时它会先 Switchover 再删 Pod ,滚动更新时先升 Secondary 后升 Primary------这些行为在原生 StatefulSet 里都需要手工兜底。
拓扑支持
| 拓扑 | Community | Percona | KubeBlocks |
|---|---|---|---|
| ReplicaSet | ✅ | ✅ | ✅ |
| Sharding | ❌ | ✅(默认开启) | ✅ |
| Arbiter | ✅ | ✅ | ✅ |
| Standalone | ❌ | ❌ | ✅(replicas=1) |
Community Operator 不支持 sharding,这是它最大的功能缺口。Percona 的 sharding 支持最为成熟,包含完整的 mongos / config server / 多 shard 链路。KubeBlocks 通过 topology: sharding 声明,同样支持完整 sharding 拓扑。
生命周期管理------拉开差距最大的地方
这是三者差距最大的领域,也是 Day-2 运维体验分化最严重的地方:
| 操作 | Community | Percona | KubeBlocks |
|---|---|---|---|
| 停启集群 | ❌ | ✅ pause/unpause | ✅ OpsRequest(Stop/Start) |
| 重启 | 手动 delete pod | 手动 delete pod | ✅ OpsRequest(组件级粒度) |
| 水平扩缩容 | 改 spec.members |
改 replsets.size |
✅ OpsRequest(scaleOut/scaleIn) |
| 垂直扩缩容 | 手动改资源 + 重建 Pod | 改 CR resources | ✅ OpsRequest(按 secondary→primary 滚动) |
| 存储扩容 | ❌ | ✅ 改 CR volumeSpec | ✅ OpsRequest |
| Switchover | ❌(需手动 rs.stepDown()) |
❌(需手动操作) | ✅ OpsRequest(可指定目标实例) |
| 参数修改 | ❌ | ✅ 改 CR mongod 配置 | ✅ ConfigMap/参数模板 |
| 指定副本下线 | ❌ | ❌ | ✅ OpsRequest |
看到规律了吗?Community Operator 基本把 Day-2 运维留给了用户自己 kubectl + mongosh 手动操作。Percona 对大部分操作提供了 CR 级别的支持。而 KubeBlocks 把这些操作全部抽象成了独立的 OpsRequest 对象。
这个区别到底意味着什么?下面来具体说。
OpsRequest:为什么"独立的运维对象"很重要
先看一个实际例子。假设你要给 MongoDB 做垂直扩容,把资源从 500m/1Gi 提到 1/1Gi。
在 Percona 里,你需要修改 PerconaServerMongoDB CR 的 resources 字段,然后等 operator 识别到变更并执行滚动更新。整个过程没有独立的"操作"概念------你修改了 CR,事情就开始发生了,至于做到哪一步、是否成功,你只能从 Pod 状态去推断。
在 KubeBlocks 里,这是一个独立的 OpsRequest:
yaml
apiVersion: operations.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:
name: mongo-cluster-vscale-ops
namespace: demo
spec:
clusterName: kb-mongodb-test
type: VerticalScaling
verticalScaling:
- componentName: mongodb
requests:
cpu: "1"
memory: 1Gi
limits:
cpu: "1"
memory: 1Gi
提交之后,可以直接 watch 进度:
bash
kubectl -n demo get opsrequest mongo-cluster-vscale-ops -w
text
NAME TYPE CLUSTER STATUS PROGRESS AGE
mongo-cluster-vscale-ops VerticalScaling kb-mongodb-test Running 0/3 32s
mongo-cluster-vscale-ops VerticalScaling kb-mongodb-test Running 1/3 55s
mongo-cluster-vscale-ops VerticalScaling kb-mongodb-test Running 2/3 82s
mongo-cluster-vscale-ops VerticalScaling kb-mongodb-test Succeed 3/3 2m18s
这里的关键不是"能扩容"------三家都能。关键是:
- 操作本身是一个 Kubernetes 对象,有名字、有状态、有进度,可以写进 GitOps 仓库;
- 进度可追踪 :
0/3 → 1/3 → 2/3 → 3/3,而不是"改了字段,不知道做到哪了"; - 失败有明确状态 :不是 Pod 起不来要自己猜,而是 OpsRequest 会变成
Failed; - 天然可审计:谁在什么时候提交了什么操作,全在 etcd 里。
OpsRequest 目前支持的操作类型:
| 类型 | 说明 |
|---|---|
Stop / Start |
停启集群,释放计算资源,保留存储 |
Restart |
按组件粒度重启 |
VerticalScaling |
调整 CPU/Memory,按 secondary→primary 滚动 |
HorizontalScaling |
增减副本数 |
VolumeExpansion |
在线扩容 PVC |
Switchover |
声明式主从切换,可指定候选实例 |
对平台团队来说,这意味着运维动作可以直接被流水线消费:前端发起扩容 → 后端生成 OpsRequest → 平台 watch 进度 → 结果回写工单。整条链路不需要 ssh 进任何 Pod。
高可用与角色感知
| 维度 | Community | Percona | KubeBlocks |
|---|---|---|---|
| HA 机制 | MongoDB 原生选举 | MongoDB 原生选举 | MongoDB 原生选举 + roleProbe |
| 角色标签 | ❌ | ❌ | ✅ kubeblocks.io/role |
| 读写分离 Service | ❌ | ❌ | ✅ 自动创建 primary + secondary-ro Service |
| Switchover | 手动 rs.stepDown() |
手动操作 | ✅ OpsRequest 声明式 |
| 缩容安全 | 可能误删 Primary | 可能误删 Primary | 先 Switchover 再删除 |
三者的 HA 底层都依赖 MongoDB 原生选举。区别在于 Kubernetes 层面能不能感知角色 。Community 和 Percona 的 Pod 标签里看不出谁是 Primary,想确认就必须进 Pod 跑 rs.status()。KubeBlocks 通过 roleProbe 把角色写到 Pod 标签上,同时自动创建基于角色的 Service------写流量走 primary,读流量走 secondary-ro。
日常运维时差距还好,突发故障排查时差距就大了:一条 kubectl get pods -L kubeblocks.io/role 看全局角色分布,还是挨个 Pod 进去敲命令------效率不在一个量级。
备份与恢复
| 维度 | Community | Percona | KubeBlocks |
|---|---|---|---|
| 内置备份 | ❌ | ✅ | ✅(PBM agent) |
| 备份方式 | --- | 逻辑 + 物理 | 逻辑 + 物理 |
| 定时备份 | --- | ✅ cron | ✅ BackupSchedule |
| PITR | --- | ✅ oplog 连续备份 | ✅ |
| 存储后端 | --- | S3 / Azure Blob / GCS / MinIO | S3 兼容存储 |
Community Operator 完全不提供备份恢复能力------这在生产场景下是个硬伤。Percona 和 KubeBlocks 都内置了 PBM(Percona Backup for MongoDB)agent,支持逻辑备份、物理备份和 PITR。
安全特性
| 维度 | Community | Percona | KubeBlocks |
|---|---|---|---|
| TLS | ✅ | ✅ | ✅ |
| 认证 | SCRAM | SCRAM + x509 | SCRAM |
Percona 额外支持静态加密(Vault / Key Secret)和 LDAP 集成,如果有相关合规要求可以关注。
监控与可观测
| 维度 | Community | Percona | KubeBlocks |
|---|---|---|---|
| Prometheus 指标 | ✅ ServiceMonitor | ✅ exporter 内置 | ✅ exporter sidecar |
| 角色可观测 | ❌(需进 Pod) | ❌(需进 Pod) | ✅ Pod 标签直接显示 |
| 操作进度可观测 | ❌ | ❌ | ✅ OpsRequest STATUS/PROGRESS |
六、综合功能对比
把前面的分析压缩成一张表:
| 功能维度 | Community Operator | Percona Operator | KubeBlocks |
|---|---|---|---|
| ReplicaSet | ✅ | ✅ | ✅ |
| Sharding | ❌ | ✅ | ✅ |
| 停启集群 | ❌ | ✅ | ✅ OpsRequest |
| 重启 | 手动 delete pod | 手动 delete pod | ✅ OpsRequest |
| 水平扩缩容 | 改 spec.members |
改 replsets.size |
✅ OpsRequest |
| 垂直扩缩容 | 手动改资源 | 改 CR resources | ✅ OpsRequest |
| 存储扩容 | ❌ | ✅ | ✅ OpsRequest |
| Switchover | ❌ | ❌ | ✅ OpsRequest |
| 备份恢复 | ❌ | ✅ | ✅ |
| PITR | ❌ | ✅ | ✅ |
| 角色感知 | ❌ | ❌ | ✅ |
| 操作可追踪 | ❌ | ❌ | ✅ |
| 多引擎统一管理 | ❌ | ❌ | ✅(30+ 引擎) |
看完这张表,画像就比较清楚了:
- Community Operator 是最简洁的起点,但 Day-2 能力基本空白;
- Percona Operator 在 MongoDB 专项能力上覆盖最全,但没有统一的运维操作层;
- KubeBlocks 在运维模型和平台化能力上有明显优势,最接近平台化交付路线。
七、为什么 KubeBlocks 更值得优先评估
前面的对比已经能看出:三者各有侧重,但选型看的不只是功能 checklist 上的打勾数量,还有团队维护这套系统的长期成本。
1)统一模型降低认知负担
如果团队只管 MongoDB,三者都可以考虑。但现实中,很少有团队只管一种数据库。当你同时要管 MongoDB、MySQL、PostgreSQL、Redis 的时候:
| 操作 | 多 Operator 方案 | KubeBlocks |
|---|---|---|
| 查看集群状态 | kubectl get mdbc / kubectl get psmdb / kubectl get mysql / ... |
kubectl get cluster |
| 查看 Pod 角色 | 进 Pod 执行各种引擎命令 | kubectl get pods -L kubeblocks.io/role |
| 垂直扩容 | 每种 Operator 改不同的字段 | OpsRequest type: VerticalScaling |
| 水平扩容 | 每种 Operator 改不同的字段 | OpsRequest type: HorizontalScaling |
学一套 API,管所有引擎。这不只是"更优雅",更是"新人上手更快、SOP 可复用、出了问题排查路径一致"。
2)OpsRequest 让运维可审计、可接入 CI/CD
这是 KubeBlocks 跟另外两种方案最根本的分界点。
Percona 和 Community 的运维本质都是"修改 CR → operator 检测变更 → 执行操作"。操作没有独立身份,进度无从追踪,审计只能依赖 etcd 级别的 CR 变更记录。
KubeBlocks 的模式是"提交 OpsRequest → operator 执行 → 对象本身记录状态和进度"。每次操作都有名字、类型、状态、进度、时间戳,天然可以被工单系统、CI/CD 流水线或自服务平台消费。
3)Addon 生态持续扩展
KubeBlocks 当前支持的引擎包括 MySQL、PostgreSQL、Redis、MongoDB、Kafka、Pulsar、ClickHouse、Elasticsearch、Milvus、Qdrant 等 30 多种。每新增一种引擎,不需要学新 Operator,同样的 Cluster YAML 就能创建实例。
对想构建数据库 PaaS 的团队来说,这大幅降低了接入新引擎的边际成本。
4)InstanceSet 解决了 StatefulSet 的实际痛点
前面提到过 InstanceSet 替代 StatefulSet 的设计。再强调一下它解决的具体问题:
- 缩容时自动先 Switchover,不会误删 Primary;
- 滚动更新按角色排序:先 Secondary 后 Primary,最大化可用性;
- 支持同一组内不同 Pod 有不同资源配置。
这些在 Community 和 Percona 里,要么需要手动操作,要么不支持。
八、选型建议
要官方原生基线?
选 MongoDB Community Operator。最贴近 MongoDB 原生 CR 模型,适合建立认知。但要做好准备:备份、sharding、声明式运维,它一个都不提供。
团队是 MongoDB 重度用户,且有安全合规硬性要求?
选 Percona Operator for MongoDB。sharding、备份/PITR、静态加密、LDAP、PMM 监控------MongoDB 专项能力覆盖面最强。代价是更高的学习曲线和更重的运维链路。
关心团队复制性、运维可追踪性,或者要同时管理多种数据库?
优先评估 KubeBlocks。
在这次实测范围内,它展现出了几个具体的优势:
- 创建简洁 :一个
ClusterCR 表达完整 MongoDB 集群,不需要额外 Secret 或特殊字段组合; - 运维可追踪 :扩缩容、重启、Switchover 都通过
OpsRequest声明式表达,状态和进度一目了然; - 角色可观测:不进 Pod 就能看到谁是 Primary,故障排查效率更高;
- 跨引擎可复用:同一套 API 管 MongoDB 和管 MySQL / PostgreSQL 没有本质区别。
如果团队不只是想"把 MongoDB 跑起来",而是想建立一套可以长期维护、对多种数据库统一管理的平台能力------这是三条路线里最短的那一条。
九、总结
回到开头的问题:在 Kubernetes 上跑 MongoDB,选哪个 Operator?
基于这次实测,三者都能完成 3 节点 ReplicaSet 的创建和 failover 恢复------Day-1 体验的差距并没有那么大。真正的分化发生在 Day-2:生命周期管理、运维可追踪性、角色感知、平台化扩展。
Community Operator 胜在轻量和官方原生;Percona Operator 胜在 MongoDB 专项深度和企业安全特性;KubeBlocks 胜在统一运维模型、OpsRequest 操作范式和多引擎平台生态。
如果只能优先投入一条主线,基于这次实测的判断:KubeBlocks 更值得优先评估。
参考文献
- MongoDB Community Operator (MCK): github.com/mongodb/mon...
- Percona Operator for MongoDB: github.com/percona/per...
- Percona Operator 文档: docs.percona.com/percona-ope...
- KubeBlocks: github.com/apecloud/ku...
- KubeBlocks Addons (含 MongoDB): github.com/apecloud/ku...
- KubeBlocks 文档: kubeblocks.io/docs/