MongoDB StatefulSet删创后数据丢失问题咨询
MongoDB StatefulSet删创后数据丢失问题解答
问题描述
在Minikube环境中,我成功创建了带有PersistentVolumeClaim(PVC)的MongoDB StatefulSet。执行kubectl delete -f X.yml删除所有资源后,再执行kubectl create -f X.yml重建,发现数据库数据丢失。请问这是预期情况吗?原因是否为每次都会创建新的PVC及全新存储卷?如何实现删创操作间的数据持久化?
附配置YAML:
apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: mongo name: mongo spec: serviceName: "mongo" podManagementPolicy: "Parallel" replicas: 1 selector: matchLabels: app: mongo template: metadata: labels: app: mongo spec: containers: - image: mongo name: mongo args: ["--dbpath","/data/db"] livenessProbe: exec: command: - mongosh - --eval - "db.adminCommand('ping')" initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 6 readinessProbe: exec: command: - mongosh - --eval - "db.adminCommand('ping')" initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 6 env: - name: MONGO_INITDB_ROOT_USERNAME valueFrom: secretKeyRef: name: mongo-creds key: username - name: MONGO_INITDB_ROOT_PASSWORD valueFrom: secretKeyRef: name: mongo-creds key: password volumeMounts: - name: "mongo-data-dir" mountPath: "/data/db" volumes: - name: "mongo-data-dir" persistentVolumeClaim: claimName: "mongo-data" --- apiVersion: v1 kind: Service metadata: labels: app: mongo name: mongo-nodeport-svc spec: ports: - port: 27017 protocol: TCP targetPort: 27017 nodePort: 32000 selector: app: mongo type: NodePort --- apiVersion: v1 kind: PersistentVolume metadata: name: mongo-data-pv spec: accessModes: - ReadWriteOnce capacity: storage: 1Gi hostPath: path: /data/mongo --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mongo-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: v1 data: password: XXX username: XXX kind: Secret metadata: creationTimestamp: null name: mongo-creds
解答
1. 这是预期情况吗?
是,在你当前的配置下,执行删创操作后数据丢失是预期结果。
2. 根本原因
你的配置违背了StatefulSet的设计规范,同时资源删除行为导致存储数据丢失:
- 手动绑定PVC而非使用StatefulSet自动管理:你没有用StatefulSet的
volumeClaimTemplates自动生成PVC,而是手动创建PVC/PV后直接在StatefulSet中引用。执行kubectl delete -f X.yml时,所有资源(包括PV、PVC、StatefulSet)都会被删除。 - PV/PV回收与重建的冲突:虽然hostPath类型的PV将数据存在Minikube节点的
/data/mongo目录,但删除PV对象后,重新创建的PV会指向该目录——但如果Minikube节点重启导致目录被清理,或者原PV进入Released状态无法被新PVC绑定,新创建的PV会重新初始化目录,最终导致数据丢失。
3. 实现删创间数据持久化的方案
方案一:使用StatefulSet的volumeClaimTemplates(推荐)
这是StatefulSet持久化存储的标准用法,让StatefulSet自动生成PVC,删除StatefulSet时默认不会删除PVC,数据会保留。
修改后的StatefulSet核心配置:
apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: mongo name: mongo spec: serviceName: "mongo" podManagementPolicy: "Parallel" replicas: 1 selector: matchLabels: app: mongo # 添加volumeClaimTemplates,自动生成PVC volumeClaimTemplates: - metadata: name: mongo-data-dir spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi template: metadata: labels: app: mongo spec: containers: - image: mongo name: mongo args: ["--dbpath","/data/db"] # 探针、环境变量配置保持不变 volumeMounts: - name: "mongo-data-dir" mountPath: "/data/db" # 移除原来手动指定的volumes字段
同时,删除YAML中手动创建的PV和PVC定义,Minikube默认的standard存储类会自动创建hostPath类型的PV,完成存储绑定。
方案二:保留手动PVC/PV,针对性删除资源
如果你坚持使用手动创建的PV/PVC,可以只删除StatefulSet和Service,保留存储相关资源:
# 仅删除StatefulSet和Service,不碰PVC、PV、Secret kubectl delete statefulset mongo service mongo-nodeport-svc
重建时只应用StatefulSet和Service的YAML片段,不重新创建PVC、PV和Secret,数据会保留在原存储卷中。
额外注意事项
- 确认PV的回收策略为
Retain(hostPath类型PV默认是该策略),避免删除PVC时自动清理PV数据:kubectl patch pv mongo-data-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' - Minikube的hostPath存储仅适合测试,生产环境建议使用NFS、云存储等持久化存储方案,避免节点重启导致数据丢失。
内容的提问来源于stack exchange,提问作者notaorb
相关产品推荐
相关产品推荐

