Kubernetes 部署 MongoDB Replica Set 指南

Kubernetes 部署 MongoDB Replica Set 指南

本文介绍如何在 Kubernetes 集群中部署 MongoDB 4.4.13 分片副本集(Replica Set),使用 DaemonSet 确保每个指定节点运行一个 MongoDB 实例,通过 hostNetwork 直接暴露端口,并配置定时备份策略。


一、架构概述

该集群采用三节点副本集架构:

节点 角色 端口 说明
mongoserver1 PRIMARY :30017 主节点,处理写入
mongoserver2 SECONDARY :30017 从节点,同步复制
mongoserver3 SECONDARY :30017 从节点,同步复制

关键设计决策

  • DaemonSet 而非 StatefulSet — 每个节点精确运行一个 Pod,与节点绑定
  • hostNetwork: true — 直接使用宿主机网络,免去 Service 端口转发开销
  • hostAliases — 通过主机名解析实现副本集节点互相发现
  • NodePort Service — 为外部客户端提供统一访问入口

二、部署配置文件

完整的 mongo.yaml 配置:

apiVersion: v1
kind: Namespace
metadata:
  name: bjac-mongo

---

apiVersion: v1
kind: Service
metadata:
  labels:
    app: mongo
  name: mongo-out
  namespace: bjac-mongo
spec:
  type: NodePort
  ports:
    - port: 30017
      targetPort: 30017
      protocol: TCP
      nodePort: 30018
  selector:
    app: mongo

---

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: mongo
  namespace: bjac-mongo
  labels:
    app: mongo
spec:
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      nodeSelector:
        mongo-server: "true"
      hostNetwork: true
      volumes:
      - name: mongostorage
        hostPath:
          path: /home/mongo/data
      hostAliases:
      - ip: "<NODE_IP_1>"
        hostnames:
        - "mongoserver1"
      - ip: "<NODE_IP_2>"
        hostnames:
        - "mongoserver2"
      - ip: "<NODE_IP_3>"
        hostnames:
        - "mongoserver3"
      containers:
      - name: mongo
        image: mongo:4.4.13
        imagePullPolicy: IfNotPresent
        command:
          - mongod
          - "--port"
          - "30017"
          - "--shardsvr"
          - "--replSet"
          - rs0
          - "--bind_ip"
          - 0.0.0.0
        ports:
        - containerPort: 30017
        volumeMounts:
        - name: mongostorage
          mountPath: /data/db/

配置要点说明

配置项 说明
kind DaemonSet 每个匹配节点运行一个 Pod,与 StatefulSet 不同
nodeSelector mongo-server: "true" 只在标记节点上部署
hostNetwork true Pod 直接使用宿主机网络栈
hostAliases 3 个节点 IP 在 Pod 内注入主机名解析,副本集通信必需
--shardsvr 分片服务器模式
--replSet rs0 副本集名称
hostPath /home/mongo/data 使用宿主机目录存储数据

三、部署步骤

3.1 为节点打标签

查看现有节点标签:

kubectl get node --show-labels=true

为 MongoDB 服务器节点打标签:

kubectl label nodes <NODE_1> mongo-server=true
kubectl label nodes <NODE_2> mongo-server=true
kubectl label nodes <NODE_3> mongo-server=true

3.2 创建数据目录

在每个 MongoDB 节点上创建数据目录:

mkdir -p /home/mongo/data

3.3 执行部署

kubectl apply -f mongo.yaml

3.4 验证部署

# 查看 DaemonSet
kubectl get DaemonSet/mongo -n bjac-mongo -o wide

# 查看 Pod
kubectl get pod -n bjac-mongo -o wide

# 查看 Service
kubectl get svc/mongo-out -n bjac-mongo -o wide

3.5 DNS 解析测试

kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh

# 在容器内执行
nslookup mongo-out.bjac-mongo.svc.cluster.local

四、初始化副本集

部署完成后,需要手动初始化副本集。

4.1 进入 Pod

kubectl exec -it pod/<MONGO_POD_NAME> -n bjac-mongo -- bash
mongo --port=30017

4.2 执行初始化命令

在 MongoDB shell 中执行:

rs.initiate({
  _id: "rs0",
  version: 1,
  protocolVersion: 1,
  members: [
    { _id: 0, host: "mongoserver1:30017", priority: 10 },
    { _id: 1, host: "mongoserver2:30017", priority: 10 },
    { _id: 2, host: "mongoserver3:30017", priority: 10 }
  ]
})

说明hostAliases 配置确保 Pod 内可以通过 mongoserver1/2/3 主机名互相解析。三个节点 priority 均为 10,MongoDB 会自动选举 PRIMARY。

4.3 查看副本集状态

rs.status()

输出应显示一个 PRIMARY 和两个 SECONDARY 节点。

4.4 客户端连接

外部客户端需要配置 hosts 解析:

<NODE_IP_1> mongoserver1
<NODE_IP_2> mongoserver2
<NODE_IP_3> mongoserver3

然后通过 NodePort 连接:

mongodb://mongoserver1:30017,mongoserver2:30017,mongoserver3:30017/?replicaSet=rs0

五、备份配置

备份流程图

MongoDB 备份采用 Docker Compose 部署独立的备份容器,通过 cron 定时执行 mongodump

5.1 Docker Compose 配置

version: '3'

services:
  db:
    restart: always
    image: mongo:4.4.13
    hostname: mongo4413
    ports:
      - "8017:27017"
    volumes:
      - /home/docker/data/mongo/db:/data/db
      - /home/docker/data/mongo/backup:/backups/mongo
    command:
      - "mongod"
      - "--shardsvr"
      - "--port"
      - "27017"
      - "--replSet"
      - "rs1"

说明:此容器与 K8s 集群中的副本集是独立的,专门用于备份操作。它加入另一个副本集 rs1 作为 SECONDARY,从该节点读取数据进行备份。

5.2 备份脚本

backup-mongo.sh

#!/bin/sh
DUMP=/usr/bin/mongodump
OUT_DIR=/backups/mongo/mongod_bak_now
TAR_DIR=/backups/mongo/mongod_bak_list
DATE=`date +%Y-%m-%d`
NOW=`date +%Y-%m-%d_%H-%M-%S`
DAYS=30
TAR_BAK="mongod_bak_$NOW.tar.gz"

cd $OUT_DIR
rm -rf $OUT_DIR/*
mkdir -p $OUT_DIR/$DATE

# 备份指定数据库
$DUMP -h <SECONDARY_IP>:30017 -d bac-ucenter -o $OUT_DIR/$DATE
$DUMP -h <SECONDARY_IP>:30017 -d bac-core-api -o $OUT_DIR/$DATE

# 压缩备份
tar -zcvf $TAR_DIR/$TAR_BAK $OUT_DIR/$DATE

# 删除 30 天前的备份
find $TAR_DIR/ -mtime +$DAYS -delete

exit

最佳实践:从 SECONDARY 节点执行 mongodump,避免影响 PRIMARY 的写入性能。

5.3 定时任务配置

crontab 文件:

32 */6 * * * root docker exec mongo-db-1 /backups/mongo/backup-mongo.sh 2>&1

每 6 小时的第 32 分钟执行一次备份。

5.4 部署备份环境

# 创建目录
mkdir -p /home/docker/compose/mongo \
  /home/docker/data/mongo/db \
  /home/docker/data/mongo/backup/mongod_bak_now \
  /home/docker/data/mongo/backup/mongod_bak_list

chmod 777 /home/docker/data/mongo

# 添加执行权限
chmod +x /home/docker/data/mongo/backup/backup-mongo.sh

# 安装 cron 配置
mv /home/docker/data/mongo/backup/crontab /etc/cron.d/backup-mongo

六、常用运维命令

操作 命令
查看副本集状态 rs.status()
查看节点配置 rs.conf()
添加副本集成员 rs.add("mongoserver4:30017")
移除副本集成员 rs.remove("mongoserver4:30017")
查看 Pod 状态 kubectl get pod -n bjac-mongo -o wide
查看 DaemonSet kubectl get DaemonSet/mongo -n bjac-mongo
进入 Pod kubectl exec -it pod/<POD_NAME> -n bjac-mongo -- bash
手动备份 docker exec mongo-db-1 /backups/mongo/backup-mongo.sh

七、注意事项

  1. hostAliases 必须配置正确 — 副本集节点间通过主机名通信,hosts 解析错误会导致初始化失败
  2. 从 SECONDARY 备份mongodump 应连接 SECONDARY 节点,避免影响 PRIMARY 性能
  3. 数据目录权限 — 确保 /home/mongo/data 目录在宿主机上存在且可写
  4. nodeSelector 标签 — 未打标签的节点不会部署 MongoDB Pod
  5. 端口冲突hostNetwork: true 模式下,30017 端口直接绑定宿主机,确保端口未被占用
  6. 备份保留策略 — 默认保留 30 天,可根据磁盘容量调整 DAYS 参数

附录:资源清单

资源类型            名称                数量
Namespace          bjac-mongo          1
Service            mongo-out (NodePort) 1
DaemonSet          mongo               3 Pod (按节点数)
hostPath Volume    /home/mongo/data    每节点 1

阅读更多

Skills系统:可扩展AI能力设计

Skills系统:可扩展AI能力设计

概述 Skills系统是AI-Native架构中的重要组件,它允许通过声明式配置扩展AI的能力。本文将介绍Skills系统的设计与实现,让大模型能够像人类专家一样具备特定领域的能力。 什么是Skills系统 概念 Skills(技能)是一种声明式的AI能力扩展机制,类似于人类的"专业技能": 通用AI助手 专业AI助手(带Skills) ┌──────────────────────┐ ┌──────────────────────────────┐ │ │ │ │ │ 用户:请帮我写代码 │ │ 用户:请帮我审查这段代码 │ │ │ │ │ │ AI:我是一个AI助手 │ │ AI:[激活

By 菱角
插件化架构设计模式

插件化架构设计模式

概述 插件化架构是一种将核心功能与扩展功能分离的设计模式,允许系统在运行时动态加载和卸载功能模块。本文将介绍如何在微服务平台中设计和实现插件化架构。 为什么需要插件化 插件化优势 1. 模块化:功能独立,边界清晰 2. 可扩展:按需加载,动态增删 3. 隔离性:插件间互不干扰 4. 可维护:独立开发、测试、部署 5. 可定制:用户按需选择功能 核心设计 架构概览 核心组件实现 1. 插件接口定义 // core/plugin.interface.ts // 插件接口 export interface IPlugin { // 插件名称 readonly name: string // 插件版本 readonly version: string // 插件配置 getConfig(): PluginConfig // 插件清单

By 菱角
gRPC服务通信设计与实践

gRPC服务通信设计与实践

概述 在微服务架构中,服务间通信是关键环节。相比REST API,gRPC提供了更高的性能和更强的类型安全。本文将介绍如何在微服务平台中设计和实现gRPC服务通信。 为什么选择gRPC gRPC vs REST对比 特性 gRPC REST 协议 HTTP/2 HTTP/1.1 序列化 Protocol Buffers (二进制) JSON (文本) 性能 高(二进制+压缩) 中(文本开销) 类型安全 强(代码生成) 弱(运行时检查) 流式通信 原生支持(双向流) 需额外实现(SSE/WebSocket) 代码生成 自动生成 手动编写 浏览器支持 需gRPC-Web 原生支持 调试难度

By 菱角
多语言微服务架构:Node.js与Python协作

多语言微服务架构:Node.js与Python协作

概述 在微服务架构中,根据场景选择最适合的编程语言是最佳实践。本文将介绍如何在微服务平台中实现Node.js与Python的协作,发挥各自技术优势。 技术选型策略 为什么混合使用 服务划分 Node.js服务(7个) 服务 功能 选择Node.js的原因 llm.api 大模型服务 高并发SSE流式响应 ucenter.api 用户中心 RESTful API标准实践 doc.api 文件服务 流式上传下载处理 resource.api 资源管理 gRPC高性能通信 rag.api 知识库服务 MongoDB集成便利 statistic.api 统计分析 事件驱动架构 pptonline.api PPT服务 与前端技术栈统一 Python服务(1个) 服务 功能 选择Python的原因

By 菱角