1. 为什么我们需要这种组合?
在当今的微服务架构中,MongoDB就像厨房里的智能冰箱,而Kubernetes就是那台自动调控温湿度的中央管理系统。当我们的应用需要处理持续增长的订单数据时,单节点MongoDB就像用小冰柜储存整条街的食材——不仅容量不够,万一断电所有食物都会变质。这时候副本集部署就如同在库房安装三台互为备份的商用冷库,而持久化存储就是确保食材不会因设备重启而丢失的保险柜机制。
2. 装备你的工具箱
在开始烹饪之前,请确认你的厨房(环境)已准备就绪:
# 查看Kubernetes集群状态
kubectl cluster-info
# 验证StorageClass配置(必须要有支持动态存储供应的存储类)
kubectl get storageclass
# 验证网络插件是否支持DNS解析(副本集通信必备)
kubectl run -i --tty busybox --image=busybox --restart=Never -- sh
# 在临时容器内执行
nslookup kubernetes.default
3. 打造MongoDB三兄弟(副本集篇)
3.1 制造专属身份证(Headless Service)
# mongo-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mongodb-svc
labels:
app: mongodb
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None # 关键参数:无头服务
selector:
app: mongodb
这个配置让每个MongoDB实例都有独立域名,就像给三胞胎兄弟各自配备专用对讲机频道。
3.2 创造容器生命体(StatefulSet配置)
# mongo-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: "mongodb-svc"
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongodb
image: mongo:6.0
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-persistent-storage
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: mongo-persistent-storage
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard" # 根据实际存储类调整
resources:
requests:
storage: 10Gi
注意第三行的serviceName
必须与前文的Service名称对应,就像为游轮配置正确的雷达识别码。
3.3 启动集群的魔法咒语
# 初始化副本集(连接任意Pod执行)
kubectl exec -it mongodb-0 -- mongosh --eval "
rs.initiate({
_id: 'rs0',
members: [
{_id: 0, host: 'mongodb-0.mongodb-svc.default.svc.cluster.local:27017'},
{_id: 1, host: 'mongodb-1.mongodb-svc.default.svc.cluster.local:27017'},
{_id: 2, host: 'mongodb-2.mongodb-svc.default.svc.cluster.local:27017'}
]
})"
# 检查副本集状态(需要等待2分钟初始化)
kubectl exec -it mongodb-0 -- mongosh --eval "rs.status()"
这里的DNS命名规则就像快递地址系统:pod-name.service-name.namespace.svc.cluster.local
4. 数据永生之术(持久化进阶篇)
4.1 存储类选择策略
当使用AWS EKS时,推荐改用gp3存储类:
# 修改volumeClaimTemplates部分
storageClassName: "gp3"
resources:
requests:
storage: 100Gi # AWS支持动态扩容
iops: 3000 # 高性能配置
throughput: 125 # MB/s单位
4.2 数据备份实战
使用k8s CronJob实现定时备份:
# mongo-backup-job.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: mongo-backup
spec:
schedule: "0 3 * * *" # 每天凌晨3点
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: mongo:6.0
command:
- /bin/sh
- -c
- |
mongodump --host=rs0/mongodb-0.mongodb-svc,mongodb-1.mongodb-svc,mongodb-2.mongodb-svc \
--gzip --archive=/backup/$(date +%Y%m%d).gz
volumeMounts:
- name: backup-volume
mountPath: /backup
restartPolicy: OnFailure
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: mongo-backup-pvc
5. 生产环境中的生存指南
5.1 网络优化技巧
为StatefulSet添加反亲和性配置:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values: ["mongodb"]
topologyKey: "kubernetes.io/hostname"
这个配置就像规定每个兄弟必须住在不同街区,避免整栋楼房倒塌的风险。
5.2 监控报警设置
使用Prometheus监控模板:
# mongo-monitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: mongo-monitor
spec:
selector:
matchLabels:
app: mongodb
endpoints:
- port: mongodb
interval: 30s
path: /metrics
配合Grafana仪表盘,实时监控副本集同步延迟、Oplog窗口等关键指标。
6. 实战中的典型问题诊断
当发现某个Pod无法加入副本集时,请按以下步骤排查:
- 检查DNS解析:
nslookup mongodb-0.mongodb-svc
- 验证网络策略是否允许27017端口通信
- 查看MongoDB日志:
kubectl logs mongodb-0 -c mongodb
- 检查存储卷状态:
kubectl describe pvc mongo-persistent-storage-mongodb-0
7. 技术组合的X光透视
7.1 优势亮点
- 自动故障转移速度比传统VM部署快3倍
- 横向扩展只需修改replicas数值
- 存储卷的动态供应比静态配置效率提升80%
- 基于DNS的服务发现机制天然适合分布式系统
7.2 需要特别注意的坑
- 必须设置合理的资源限制(CPU/Memory)
- 避免使用HostPath类型的存储卷
- 跨可用区部署时的延迟问题
- Oplog大小需要根据业务写入量调整
8. 最佳实践路线图
- 开发环境使用3节点副本集
- 预发布环境开启持久化日志
- 生产环境增加:
- 定期滚动证书
- 启用TLS加密通信
- 配置网络策略白名单
- 设置磁盘空间预警阈值(建议80%)
9. 场景适用性分析
这种方案特别适合:
- 日活百万的社交应用用户数据存储
- 物联网设备的实时数据收集
- 需要AB测试功能的电商平台
- 金融行业的交易流水记录
但对以下场景需要谨慎:
- 单日数据写入量超过TB级别
- 需要跨区域多集群部署
- 强一致性与高性能写入的极端要求