StatefulSet/Deployment重启后Persistent Volume内容丢失问题排查
问题:Kubernetes中PV内容在Pod重启后丢失
在Kubernetes环境部署SFTP服务时,使用StatefulSet或Deployment重启创建新Pod后,Persistent Volume(PV)中的内容会丢失。当前PVC和StatefulSet配置如下:
PVC配置
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: sftp-pvc labels: app: sftp spec: accessModes: - ReadWriteOnce resources: requests: storage: 3Gi
StatefulSet配置
apiVersion: apps/v1 kind: StatefulSet metadata: name: sftp-deployment spec: serviceName: sftp-statfulset replicas: 2 selector: matchLabels: app: sftp template: metadata: labels: app: sftp spec: volumes: - name: sftp-storage persistentVolumeClaim: claimName: sftp-pvc containers: - name: sftp image: atmoz/sftp ports: - containerPort: 22 env: - name: SFTP_USERS value: "$(SFTP_USERNAME):$(SFTP_PASSWORD):::$(SFTP_ROOT_DIRECTORY)" volumeMounts: - name: ftm-sftp-storage mountPath: "/home/$(SFTP_USERNAME)/$(SFTP_ROOT_DIRECTORY)" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
问题分析与解决方案
1. 卷挂载名称不匹配(核心问题)
你的StatefulSet配置中,volumes定义的卷名称是sftp-storage,但volumeMounts里引用的名称是ftm-sftp-storage——名称不匹配会导致容器无法正确挂载PVC,转而使用临时emptyDir存储,这才是Pod重启后内容丢失的根本原因。
修正方法:将volumeMounts中的name改为与volumes一致的sftp-storage:
volumeMounts: - name: sftp-storage mountPath: "/home/$(SFTP_USERNAME)/$(SFTP_ROOT_DIRECTORY)"
2. StatefulSet多副本与PVC访问模式冲突
你的PVC使用ReadWriteOnce访问模式,意味着该卷只能被单个节点上的一个Pod挂载。但StatefulSet设置了replicas: 2,这会导致第二个Pod无法挂载PVC,长期处于Pending状态。
如果需要多副本SFTP服务,有两种方案:
- 改用支持
ReadWriteMany(RWX)的存储类(如NFS、CephFS等),确保多个Pod可同时读写同一份存储 - 为StatefulSet启用独立PVC特性:StatefulSet会为每个Pod自动创建带编号的PVC(如
sftp-storage-0、sftp-storage-1),每个Pod拥有独立存储。需修改配置,移除spec.template.spec.volumes,添加spec.volumeClaimTemplates:
apiVersion: apps/v1 kind: StatefulSet metadata: name: sftp-deployment spec: serviceName: sftp-statfulset replicas: 2 selector: matchLabels: app: sftp volumeClaimTemplates: - metadata: name: sftp-storage spec: accessModes: - ReadWriteOnce resources: requests: storage: 3Gi template: metadata: labels: app: sftp spec: containers: - name: sftp image: atmoz/sftp ports: - containerPort: 22 env: - name: SFTP_USERS value: "$(SFTP_USERNAME):$(SFTP_PASSWORD):::$(SFTP_ROOT_DIRECTORY)" volumeMounts: - name: sftp-storage mountPath: "/home/$(SFTP_USERNAME)/$(SFTP_ROOT_DIRECTORY)" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
3. 验证存储类的持久化特性
确认自动创建PV的存储类是否支持持久化(如云厂商EBS、分布式存储等),避免使用hostPath(节点本地存储,Pod调度到其他节点会丢失内容)或临时存储类。可通过以下命令查看存储类:
kubectl get storageclasses
验证步骤
- 应用修正后的配置:
kubectl apply -f <你的配置文件路径>.yaml - 查看Pod状态:
kubectl get pods,确保所有Pod正常运行 - 连接SFTP创建测试文件,重启Pod后再次检查文件是否存在
内容的提问来源于stack exchange,提问作者f.bele
相关产品推荐
相关产品推荐

