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

阅读更多

Ghost 邮箱订阅功能在中国大陆的困境:Mailgun 注册受阻实录

Ghost 邮箱订阅功能在中国大陆的困境:Mailgun 注册受阻实录

本文记录了 Ghost 博客邮箱订阅功能因 Mailgun 在中国大陆无法注册而被迫关闭的完整过程,包括注册尝试、工单沟通及最终应对方案。 一、背景:Ghost 与 Mailgun Ghost 博客平台内置了邮箱订阅(Newsletter)功能,读者可以通过输入邮箱地址订阅博客更新,Ghost 会自动将新文章以邮件形式推送给订阅者。这一功能的邮件发送能力依赖于第三方邮件服务——Mailgun。 Ghost 官方推荐使用 Mailgun 作为邮件传输层,配置方式如下: 配置项 说明 示例值 mail.from 发件人地址 newsletter@yourdomain.com mail.transport 传输协议 SMTP mail.options.host SMTP 主机 smtp.mailgun.org mail.options.port

By 菱角
Kubernetes 全栈监控体系:kube-prometheus-stack + 7 大 Exporter 生产实践

Kubernetes 全栈监控体系:kube-prometheus-stack + 7 大 Exporter 生产实践

本文基于 kube-prometheus-stack Helm Chart 在 Kubernetes 上构建完整监控体系的实战,覆盖 Prometheus、Grafana、Alertmanager 及 7 个专用 Exporter 的部署与配置。 一、监控体系全景架构 整套监控以 kube-prometheus-stack 为核心,通过 ServiceMonitor CRD 自动发现并采集 7 大数据源,配合 Alertmanager 分级告警与 Grafana 可视化: 组件 版本 作用 Prometheus v2.45.0 指标采集与存储,10 天数据保留 Alertmanager v0.25.0 告警路由与邮件推送,2 副本 HA

By 菱角
基于 Docker Compose 部署 Apache APISIX:全栈 API 网关实践

基于 Docker Compose 部署 Apache APISIX:全栈 API 网关实践

本文基于 APISIX 3.9.1 + Dashboard 3.0.1 + etcd 3.5.15 + Prometheus + Grafana 的生产级 Docker Compose 部署实践。 一、整体架构 本次部署采用 Docker Compose 编排五大组件,形成从配置管理到流量监控的完整闭环: 组件 版本 作用 端口 APISIX 3.9.1-debian API 网关核心,路由转发、插件执行 9080/9443 Dashboard 3.0.1-alpine 可视化配置管理界面 9000 etcd 3.5.15

By 菱角
在 Kubernetes 上部署 Apache Flink:生产实战指南

在 Kubernetes 上部署 Apache Flink:生产实战指南

本文基于 Flink 1.15.2 + Kubernetes 的生产环境部署实践。 一、架构概览 Flink 在 Kubernetes 上采用经典的 JobManager + TaskManager 主从架构,JobManager 负责作业调度与协调,TaskManager 承载实际的计算任务。 资源分配一览 组件 作用 副本数 Task Slots 内存配置 JobManager 作业调度、Checkpoint 管理、协调 1 — 8G TaskManager 执行计算任务 3 80/Pod 48G 总计 — 4 240 — 二、Namespace 隔离 为 Flink 创建独立 Namespace,

By 菱角