MongoDB 高可用集群部署

MongoDB 高可用集群部署

一、方案概述

1.1 目标

在 K8s 高可用集群上,部署一套 MongoDB 高可用集群,具备:

  • 高可用:3 数据节点副本集,容忍 1 个节点故障
  • 自动故障转移:主节点故障时,从节点自动提升为主
  • 仲裁节点:避免偶数节点脑裂
  • 持久化:每个节点独立 PVC,数据落盘
  • 外部访问:Ingress + HTTPS(可选)

1.2 技术选型

组件 用途
Bitnami MongoDB Helm Chart 部署 MongoDB 副本集
StatefulSet 管理 MongoDB Pod
PersistentVolumeClaim 每个节点的持久化存储
Longhorn 分布式存储
MongoDB Replica Set 副本集高可用

1.3 架构

复制代码
应用
  ↓
Service: mongodb.mongodb.svc.cluster.local:27017
  ↓
MongoDB Replica Set (3 数据节点 + 1 仲裁)
  ├── mongodb-0 (PRIMARY)
  ├── mongodb-1 (SECONDARY)
  ├── mongodb-2 (SECONDARY)
  └── mongodb-arbiter-0 (ARBITER)
  ↓
PersistentVolume (longhorn)

二、前置条件

2.1 集群状态

  • K8s 集群 kubectl get nodes 全部 Ready
  • Longhorn 已部署,longhorn StorageClass 就绪
  • 节点数量 ≥ 3(保证副本集能选举)

2.2 存储要求

MongoDB 需要 PVC 持久化数据。必须提前配好 StorageClass。

复制代码
kubectl get storageclass

这命令看 StorageClass 列表,预期看到 longhorn。

2.3 Longhorn 存储设置

这是关键步骤,不改的话,Longhorn 会因为"空间不足"拒绝调度副本。

复制代码
kubectl patch settings.longhorn.io storage-over-provisioning-percentage -n longhorn-system --type=merge -p '{"value":"200"}'

这条命令允许 Longhorn 超配到磁盘总容量的 200%。

复制代码
kubectl patch settings.longhorn.io storage-minimal-available-percentage -n longhorn-system --type=merge -p '{"value":"10"}'

这条命令把最小可用空间从 25% 降到 10%。

2.4 镜像网络要求

MongoDB 的镜像在 registry-1.docker.io/bitnami/mongodb 上。Bitnami 从 2025 年 8 月 28 日起移除了 Docker Hub 公共目录的免费镜像,直接拉会返回 403。

解决方案 :用 bitnami/mongodb:latest 标签,DaoCloud 代理可用。

复制代码
ansible k8s_cluster -i inventory.ini -m shell -a "crictl pull docker.m.daocloud.io/bitnami/mongodb:latest" -b

这条命令在所有节点上从 DaoCloud 代理拉 bitnami/mongodb:latest。

复制代码
ansible k8s_cluster -i inventory.ini -m shell -a "ctr -n k8s.io images tag docker.m.daocloud.io/bitnami/mongodb:latest registry-1.docker.io/bitnami/mongodb:latest" -b

这条命令给镜像打标签,让 containerd 认为本地有 registry-1.docker.io/bitnami/mongodb:latest。


三、下载 MongoDB Chart

3.1 从 DaoCloud 拉取

不能用 helm repo add bitnami,因为 Bitnami 的 chart 走 Docker Hub OCI,国内不通。

复制代码
helm pull oci://docker.m.daocloud.io/bitnamicharts/mongodb --version 19.3.0

这条命令从 DaoCloud 代理拉 MongoDB chart。

预期输出:

复制代码
Pulled: docker.m.daocloud.io/bitnamicharts/mongodb:19.3.0
Digest: sha256:fe65e88b838f225d13a1df988e323d47715c7c85f14863f5b05837c12ceed000

下载后本地会有 :mongodb-19.3.0.tgz


四、部署 MongoDB

4.1 生成密码和密钥

复制代码
openssl rand -base64 24

这条命令生成一个随机密码,执行两次,分别得到 root 密码和副本集密钥。

把两次输出保存下来。

4.2 安装 MongoDB

复制代码
helm install mongodb ./mongodb-19.3.0.tgz \
  --namespace mongodb \
  --create-namespace \
  --set architecture=replicaset \
  --set replicaCount=3 \
  --set auth.rootPassword=<root密码> \
  --set auth.replicaSetKey=<副本集密钥> \
  --set persistence.storageClass=longhorn \
  --set persistence.size=10Gi

这条命令用本地 chart 安装 MongoDB 副本集。

逐项解析:

参数 含义
mongodb release 名
./mongodb-19.3.0.tgz 本地 chart 包
--namespace mongodb 装到 mongodb 命名空间
--create-namespace 自动创建命名空间
architecture=replicaset 副本集模式
replicaCount=3 3 个数据节点
auth.rootPassword root 密码
auth.replicaSetKey 副本集内部认证密钥
persistence.storageClass=longhorn 用 Longhorn 存储
persistence.size=10Gi 每个节点 10Gi

4.3 观察 Pod 启动

复制代码
kubectl get pods -n mongodb -w

这条命令观察 Pod 启动,按 Ctrl+C 退出。

预期:

复制代码
mongodb-0           1/1   Running
mongodb-1           1/1   Running
mongodb-2           1/1   Running
mongodb-arbiter-0   1/1   Running

注意 :chart 会自动加一个 arbiter 节点,用于投票,不存数据。


五、验证 MongoDB

5.1 查看 Pod 和 PVC

复制代码
kubectl get pods -n mongodb
kubectl get pvc -n mongodb

这两条命令看 Pod 和 PVC 状态。

预期:

  • 4 个 Pod 全部 Running。
  • PVC 全部 Bound,STORAGECLASS 是 longhorn。

5.2 查看副本集状态

复制代码
kubectl exec -it -n mongodb mongodb-0 -- mongosh -u root -p <root密码> --authenticationDatabase admin --eval "rs.status()"

这条命令查看副本集状态。

预期:

  • 1 个 PRIMARY
  • 2 个 SECONDARY
  • 1 个 ARBITER
  • 所有成员 health: 1

5.3 测试读写

复制代码
kubectl exec -it -n mongodb mongodb-0 -- mongosh -u root -p <root密码> --authenticationDatabase admin --eval "db.test.insertOne({name: 'hello'})"

这条命令插入一条测试数据。

复制代码
kubectl exec -it -n mongodb mongodb-0 -- mongosh -u root -p <root密码> --authenticationDatabase admin --eval "db.test.find()"

这条命令查询数据,预期返回刚才插入的记录。


六、应用接入

6.1 连接信息

在集群内部:

用途 地址
MongoDB mongodb.mongodb.svc.cluster.local:27017

简写(同命名空间):

复制代码
mongodb:27017

跨命名空间:

复制代码
mongodb.mongodb.svc.cluster.local:27017

用户名 :root

密码:从 Secret 取。

6.2 取密码

复制代码
kubectl get secret -n mongodb mongodb -o jsonpath='{.data.mongodb-root-password}' | base64 -d
echo

这条命令从 Secret 取 root 密码。

6.3 应用配置示例

Python (pymongo):

复制代码
from pymongo import MongoClient

client = MongoClient(
    'mongodb://root:<密码>@mongodb.mongodb.svc.cluster.local:27017/?replicaSet=rs0&authSource=admin'
)

Node.js (mongodb):

复制代码
const { MongoClient } = require('mongodb');

const client = new MongoClient(
  'mongodb://root:<密码>@mongodb.mongodb.svc.cluster.local:27017/?replicaSet=rs0&authSource=admin'
);

Java (mongodb-driver):

复制代码
MongoClient client = MongoClients.create(
    "mongodb://root:<密码>@mongodb.mongodb.svc.cluster.local:27017/?replicaSet=rs0&authSource=admin"
);

Go (mongo-go-driver):

复制代码
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(
    "mongodb://root:<密码>@mongodb.mongodb.svc.cluster.local:27017/?replicaSet=rs0&authSource=admin",
))

6.4 部署后端服务到 K8s

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-backend
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-backend
  template:
    metadata:
      labels:
        app: my-backend
    spec:
      containers:
        - name: my-backend
          image: my-backend:latest
          ports:
            - containerPort: 8080
          env:
            - name: MONGODB_HOST
              value: "mongodb.mongodb.svc.cluster.local"
            - name: MONGODB_PORT
              value: "27017"
            - name: MONGODB_USER
              value: "root"
            - name: MONGODB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mongodb
                  key: mongodb-root-password

七、常见问题

7.1 Pod 卡在 ImagePullBackOff

原因 :MongoDB 镜像在 registry-1.docker.io 上,国内拉取超时。

解决:

复制代码
ansible k8s_cluster -i inventory.ini -m shell -a "crictl pull docker.m.daocloud.io/bitnami/mongodb:latest" -b
ansible k8s_cluster -i inventory.ini -m shell -a "ctr -n k8s.io images tag docker.m.daocloud.io/bitnami/mongodb:latest registry-1.docker.io/bitnami/mongodb:latest" -b
kubectl delete pod -n mongodb --all

7.2 Bitnami 镜像 403

原因:Bitnami 从 2025 年 8 月 28 日起移除了 Docker Hub 公共目录的免费镜像。

解决 :用 bitnami/mongodb:latest 标签,DaoCloud 代理可用。

7.3 PVC 绑不上

原因:Longhorn 卷调度失败。

排查:

复制代码
kubectl get volumes.longhorn.io -n longhorn-system
kubectl get volume.longhorn.io <volume-name> -n longhorn-system -o yaml | grep -A5 "type: Scheduled"

如果报 insufficient storage:

复制代码
kubectl patch settings.longhorn.io storage-over-provisioning-percentage -n longhorn-system --type=merge -p '{"value":"200"}'
kubectl patch settings.longhorn.io storage-minimal-available-percentage -n longhorn-system --type=merge -p '{"value":"10"}'

7.4 副本集 PRIMARY 选举失败

原因:节点不够,或网络不通。

排查:

复制代码
kubectl logs -n mongodb mongodb-0 --tail=50

关注:

  • election failed
  • not enough healthy nodes

7.5 写操作失败

原因 :没有 PRIMARY,或多数派不可用。

排查:

复制代码
kubectl exec -it -n mongodb mongodb-0 -- mongosh -u root -p <密码> --authenticationDatabase admin --eval "rs.status()"

如果所有节点都是 SECONDARY,说明选举失败。


八、常用操作

8.1 查看 MongoDB 状态

复制代码
kubectl get pods -n mongodb
kubectl get pvc -n mongodb
kubectl get svc -n mongodb

8.2 查看日志

复制代码
kubectl logs -n mongodb mongodb-0 --tail=100

8.3 连接 MongoDB

复制代码
kubectl exec -it -n mongodb mongodb-0 -- mongosh -u root -p <密码> --authenticationDatabase admin

8.4 扩容

复制代码
helm upgrade mongodb ./mongodb-19.3.0.tgz \
  --namespace mongodb \
  --set replicaCount=5

这条命令把副本集从 3 节点扩到 5 节点。

8.5 删除 MongoDB

复制代码
helm uninstall mongodb -n mongodb
kubectl delete pvc -n mongodb --all
kubectl delete namespace mongodb

警告 :删除 PVC 会删除所有数据,操作前先备份。


九、架构总结

9.1 组件清单

组件 数量 作用
mongodb 3 数据节点,1 主 2 从
mongodb-arbiter 1 仲裁节点,不存数据,只投票
StatefulSet 1 管理 MongoDB Pod
PVC 3 每个数据节点一块存储
Service 2 集群内部通信和客户端入口
Secret 1 root 密码

9.2 端口速查

端口 用途
27017 MongoDB 客户端连接
27018 MongoDB 内部通信

9.3 高可用机制

故障场景 影响 恢复方式
从节点故障 无影响 主节点继续服务,从节点重建后重新同步
主节点故障 短暂不可写 从节点自动选举为新主,10-30 秒恢复
仲裁节点故障 无影响 只影响选举,不影响读写
多个节点故障 可能不可写 如果超过半数节点故障,副本集停止服务

9.4 已知隐患

隐患 影响 解决方案
Longhorn 空间调度保守 卷报 insufficient storage 改 over-provisioning 和 minimal-available
Bitnami 免费镜像移除 无法拉取最新镜像 用 bitnami/mongodb:latest
registry-1.docker.io 超时 镜像拉不下来 用 DaoCloud 代理拉并打标签
未配备份 数据无法恢复 用 mongodump 定期备份

十、总结

这套 MongoDB 基于 Bitnami Helm Chart 部署,提供了:

  • 高可用:3 数据节点副本集 + 1 仲裁节点,容忍 1 个节点故障
  • 自动故障转移:主节点故障时,从节点自动提升
  • 持久化:每个数据节点独立 PVC
  • 声明式管理:Helm chart 一条命令部署

部署中最容易踩的坑:

  1. Bitnami 免费镜像移除 :必须用 bitnami/mongodb:latest 标签。
  2. registry-1.docker.io 超时:必须配 DaoCloud 代理拉镜像并打标签。
  3. Longhorn 空间调度保守 :改 storage-over-provisioning-percentage=200 和 storage-minimal-available-percentage=10。
  4. chart 拉取超时:用 DaoCloud 的 OCI 代理。

解决了这四个问题,MongoDB 就能稳定运行。

相关推荐
YOLO数据集集合1 小时前
风机叶片缺陷检测数据集 | 风机叶片 缺陷检测 风电运维 无人机巡检 细粒度分类9126期
运维·分类·无人机·风电叶片·风力·叶片缺陷
爱签AI电子合同1 小时前
电子合同大批量怎么测?并发与批量处理维度专项测评
服务器·数据库·人工智能·企业微信·电子签名
JosieBook1 小时前
【数据库】MySQL 实战精通系列 · 第4篇:索引原理与执行计划实战
android·数据库·mysql
亚川楼宇自控系统数据中心厂家1 小时前
3D 数字孪生赋能电气综合保护监控:看得见的电力安全防线
运维
m0_547486661 小时前
《数据库原理、技术与应用:MySQL》全套PPT课件2026
数据库·mysql
北冥有鱼被烹1 小时前
NVIDIA DGX/HGX 服务器全景深度解析:从 H100 到 GB300,专业算力选型必读
运维·服务器·网络·python
JosieBook1 小时前
【数据库】MySQL 实战精通系列 · 第1篇:MySQL 全局观与实战环境搭建
数据库·mysql·adb
霸道流氓气质1 小时前
LangGraph式图编排引擎Java实现:状态机模型、Checkpoint恢复与生产级落地实战
java·开发语言·数据库
程序员-Benothing1 小时前
Linux系统启动流程详解:BIOS/UEFI、GRUB、initramfs、systemd
linux·运维·服务器