You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes文件服务器文件不持久化问题求助

Kubernetes中Pod重启后文件服务器/public目录无法持久化的问题排查与解决

问题现象

在DigitalOcean和GKE环境中部署文件服务器后,Pod运行期间/public路径下的文件可正常读写,但Pod被删除或重启后,该目录会恢复到初始状态。已配置PersistentVolumeClaim、Deployment、StorageClass及PersistentVolume,相关配置清单见下文。

配置清单

PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: file-claim
  namespace: u-e
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
  storageClassName: "do-block-storage-retain"

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fileapp
  namespace: u-e
  labels:
    app: file
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: file
  template:
    metadata:
      labels:
        app: file
    spec:
      containers:
        - name: fileapp
          image: ghcr.io/myvarlik/file
          ports:
            - containerPort: 8888
          volumeMounts:
            - mountPath: "/public"
              name: filevolume
      volumes:
        - name: filevolume
          persistentVolumeClaim:
            claimName: file-claim
      imagePullSecrets:
        - name: gh-regcred

StorageClass

allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  creationTimestamp: "2022-09-23T06:31:00Z"
  labels:
    c3.doks.digitalocean.com/component: csi-controller-service
    c3.doks.digitalocean.com/plane: data
    doks.digitalocean.com/managed: "true"
  name: do-block-storage-retain
  resourceVersion: "8814934"
  uid: f711cf4d-efe9-4c63-bd6f-476b684818a8
provisioner: dobs.csi.digitalocean.com
reclaimPolicy: Retain
volumeBindingMode: Immediate

PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: dobs.csi.digitalocean.com
    volume.kubernetes.io/provisioner-deletion-secret-name: ""
    volume.kubernetes.io/provisioner-deletion-secret-namespace: ""
  creationTimestamp: "2022-11-13T09:41:49Z"
  finalizers:
  - kubernetes.io/pv-protection
  - external-attacher/dobs-csi-digitalocean-com
  name: pvc-74053a19-97cf-49e3-bdcc-7481c57c82b2
  resourceVersion: "17951524"
  uid: 8a0bb8df-6801-4c44-ab5f-7f065ed22037
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 5Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: file-claim
    namespace: u-e
    resourceVersion: "17950915"
    uid: 74053a19-97cf-49e3-bdcc-7481c57c82b2
  csi:
    driver: dobs.csi.digitalocean.com
    fsType: ext4
    volumeAttributes:
      storage.kubernetes.io/csiProvisionerIdentity: 1663943304029-8081-dobs.csi.digitalocean.com
    volumeHandle: 651836fc-6337-11ed-8354-0a58ac14d348
  persistentVolumeReclaimPolicy: Retain
  storageClassName: do-block-storage-retain
  volumeMode: Filesystem
status:
  phase: Bound

核心原因分析

从配置来看,PV/PVC绑定正常、挂载路径配置正确,问题大概率出在容器镜像的初始化逻辑:

  • 容器镜像的/public目录自带初始文件,且启动脚本存在**无条件将默认文件复制到/public**的逻辑
  • 每次Pod重启时,该脚本会覆盖PVC中存储的用户文件,导致目录回到初始状态

排查步骤

  1. 检查容器启动脚本
    进入运行中的Pod,查看启动脚本或ENTRYPOINT/CMD逻辑:

    kubectl exec -n u-e <fileapp-pod-name> -- cat /entrypoint.sh  # 替换为实际脚本路径
    kubectl exec -n u-e <fileapp-pod-name> -- ps aux  # 查看进程启动命令
    

    确认是否存在类似cp -r /default-files/* /public/的无条件复制操作。

  2. 验证PVC存储正确性
    创建临时测试Pod挂载目标PVC,直接查看存储内容:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pvc-mount
      namespace: u-e
    spec:
      containers:
      - name: test-container
        image: busybox:latest
        command: ["sleep", "3600"]
        volumeMounts:
        - name: file-volume
          mountPath: /test-storage
      volumes:
      - name: file-volume
        persistentVolumeClaim:
          claimName: file-claim
    

    执行命令查看PVC内的文件:

    kubectl apply -f test-pod.yaml
    kubectl exec -n u-e test-pvc-mount -- ls -la /test-storage
    

    如果能看到用户之前写入的文件,说明PVC存储正常,问题确在容器初始化逻辑。

解决方案

方案1:修改容器启动脚本,避免覆盖已有文件

将启动脚本中的无条件复制逻辑,改为仅当/public为空时才初始化:

# 原逻辑
# cp -r /default/public/* /public/

# 修改后逻辑
if [ -z "$(ls -A /public)" ]; then
  cp -r /default/public/* /public/
fi

重新构建镜像并推送,更新Deployment的镜像版本。

方案2:调整挂载路径,绕过容器初始化目录

若无法修改容器镜像,可将PVC挂载到/public的子目录,同时修改应用的文件存储路径:
修改Deployment的volumeMounts配置:

volumeMounts:
  - mountPath: "/public/user-files"
    name: filevolume

确保应用配置中,文件存储路径指向/public/user-files。

方案3:确认PV/PVC状态无异常

检查PV/PVC的绑定状态及事件:

kubectl get pv,pvc -n u-e
kubectl describe pvc file-claim -n u-e

确保状态为Bound,无挂载错误或权限异常事件。

内容的提问来源于stack exchange,提问作者Muhammed Yahya Varlık

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:25:25