K8s StatefulSet中MongoDB重启后数据及副本集配置丢失问题
部署配置
1. Service配置(注意:存在重复定义,建议合并)
--- apiVersion: v1 kind: Service metadata: namespace: mongodb name: mongodb annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" spec: type: LoadBalancer ports: - protocol: TCP port: 27017 targetPort: 27017 selector: app: mongodb --- apiVersion: v1 kind: Service metadata: namespace: mongodb name: mongodb annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" spec: type: LoadBalancer ports: - protocol: TCP port: 27017 targetPort: 27017 selector: app: mongodb
2. StatefulSet配置
--- apiVersion: apps/v1 kind: StatefulSet metadata: name: mongodb namespace: mongodb spec: selector: matchLabels: app: mongodb serviceName: mongodb replicas: 3 template: metadata: labels: app: mongodb spec: containers: - name: mongodb image: private-repo/mongo:7.0 imagePullPolicy: Always args: - --bind_ip_all - --replSet - rs0 - --dbpath - /data/db - --keyFile - /etc/mongo/keyfile - --setParameter - authenticationMechanisms=SCRAM-SHA-256 - --auth - --wiredTigerCacheSizeGB - "6" ports: - name: mongodb containerPort: 27017 volumeMounts: - name: mongodb-pvc mountPath: /data envFrom: - configMapRef: name: mongodb - secretRef: name: mongodb volumeClaimTemplates: - metadata: name: mongodb-pvc namespace: mongodb spec: accessModes: ["ReadWriteOnce"] storageClassName: premium-retain resources: requests: storage: 256Gi
3. Secret配置
--- apiVersion: v1 kind: Secret metadata: name: mongodb namespace: mongodb type: Opaque stringData: MONGO_INITDB_ROOT_USERNAME: "USERNAME" MONGO_INITDB_ROOT_PASSWORD: "PASSWORD" MONGO_INITDB_DATABASE: "db"
4. ConfigMap配置
--- apiVersion: v1 kind: ConfigMap metadata: name: mongodb namespace: mongodb labels: app: mongodb data: ENV: "prod"
5. Dockerfile
FROM mongo:7.0 COPY /mongodb-keyfile /etc/mongo/keyfile RUN chown -R 999:999 /etc/mongo/keyfile RUN chmod 400 /etc/mongo/keyfile
问题原因分析及解决方案
核心原因
副本集配置存储损坏:MongoDB副本集的配置信息存在
local数据库中,该库与业务数据同存于/data/db目录。磁盘IO饱和导致Pod崩溃时,local库的WiredTiger元数据文件可能损坏,重启后MongoDB无法加载副本集配置,进入未初始化状态,即使业务数据文件完好也无法识别。全量重启导致集群无有效配置源:无论是Deployment还是StatefulSet,当所有Pod同时重启时,没有节点能提供可用的副本集配置,每个节点都会认为自己是新节点,无法自动恢复集群。
磁盘压力触发的数据一致性问题:导入数据时IO过载,可能触发WiredTiger的故障保护,导致部分数据文件(尤其是元数据)损坏,MongoDB重启后无法自动修复,只能重新初始化。
解决方案
优化磁盘IO性能:
- 确认存储类
premium-retain的IOPS配额满足导入需求,必要时临时调高配额,或分批导入数据降低IO压力。 - 调整
wiredTigerCacheSizeGB参数,避免缓存占用过多内存引发磁盘交换,进一步加剧IO负载。
- 确认存储类
避免全量Pod重启:
- 对StatefulSet执行滚动重启,每次仅重启一个Pod,确保集群始终有可用节点提供配置。
- 添加优雅关闭配置,给MongoDB足够时间完成数据刷盘:
spec: template: spec: terminationGracePeriodSeconds: 300 containers: - name: mongodb lifecycle: preStop: exec: command: ["mongosh", "--eval", "db.adminCommand({ shutdown: 1, force: false })"]
手动恢复配置与数据:
当业务数据文件完好但副本集配置丢失时:- 停止所有MongoDB Pod,仅启动一个节点,添加
--noReplSet参数以单实例模式启动。 - 登录MongoDB,删除损坏的
local.system.replset集合,然后执行rs.initiate()重新初始化副本集,此时业务数据会被保留。
- 停止所有MongoDB Pod,仅启动一个节点,添加
备份副本集配置:
定期执行rs.conf()导出副本集配置并存储到外部,集群配置丢失时可快速导入恢复。
内容的提问来源于stack exchange,提问作者Dimi
相关产品推荐
相关产品推荐

