在 Kubernetes 中,Pod 本身是无状态的,容器一旦重启或被调度到新节点,原有数据就会丢失。为了保证数据的持久化和共享,K8s 提供了 Volume 机制。

Volume 的类型非常多,但在日常实践中,最常用的就是几类:emptyDir、hostPath、本地 PV、NFS 静态 PV、以及基于 NFS 的动态卷。

这篇文章我会把这几种方式一次讲清楚,并结合配置示例,帮你快速上手

1、使用 emptyDir(最简单的临时存储)

emptyDir 是最常用也最简单的 Volume 类型,它会在 Pod 启动时创建一个空目录,Pod 删除时目录也会被清空。适用于 临时缓存日志文件 等场景。

配置示例:

volumes:
  -name:jar-vol
    emptyDir: {}

containers:
-name:app
image:myapp:v1
volumeMounts:
    -name:jar-vol
      mountPath:/var/app/
    -name:logs
      mountPath: /home/listen/Apps/logs

📌 特点:

  • 目录生命周期与 Pod 一致。

  • 容器重启不会丢,但 Pod 删除就没了。

  • 适合临时文件或缓存。


2、使用 hostPath(挂载宿主机目录)

有时我们希望容器能直接访问节点上的目录或文件,这时可以用 hostPath。

volumes:
  - name: logs
    hostPath:
      path: /logs/
      type: DirectoryOrCreate

📌 特点:

  • 可以直接访问宿主机的目录。

  • Pod 重启数据不会丢失,但如果 Pod 被调度到另一台节点,就找不到数据。

  • 适合调试环境,生产中需谨慎使用。


3、使用本地静态 PV(local PersistentVolume)

相比直接用 hostPath,本地 PV 是更推荐的方式。它会将节点本地存储抽象成 PV 供 Pod 绑定,结合 PVC 使用。

apiVersion: v1
kind:PersistentVolume
metadata:
name:local-pv
spec:
persistentVolumeReclaimPolicy:Retain
capacity:
    storage:10Gi
accessModes:
    -ReadWriteOnce
storageClassName:local-storage
local:
    path:/mnt/disks/ssd1
nodeAffinity:
    required:
      nodeSelectorTerms:
        -matchExpressions:
            -key:kubernetes.io/hostname
              operator:In
              values:
                - node1

📌 特点:

  • 数据绑定到节点,持久化效果比 hostPath 更规范。

  • 仍然存在 Pod 跨节点无法访问数据的问题。

4、Pod 直接挂载 NFS(最简 NFS 方式)

如果你有一台 NFS 服务器,可以直接把它挂到 Pod 上使用。

volumes:
- name: nfs
  nfs:
    path: /nfs
    server: 192.168.x.x
    readOnly: false

📌 特点:

  • 最快的 NFS 使用方式,直接挂载即可。

  • 适合快速实验或低复杂度应用。

  • 没有 PVC 绑定,灵活性差,管理性不足。


5、使用 NFS 静态 PV(更规范的 NFS 挂载)

在生产环境中,推荐通过 PV + PVC 的方式挂载 NFS。

1)定义 StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: manual-nfs-storage
provisioner: kubernetes.io/no-provisioner

2)定义 PV:

apiVersion: v1
kind:PersistentVolume
metadata:
name:nfs-pv001
spec:
capacity:
    storage:1Gi
accessModes:
    -ReadWriteMany
storageClassName:manual-nfs-storage
nfs:
    path:/nfs
    server:192.x.x.x

3)定义 PVC:

apiVersion: v1
kind:PersistentVolumeClaim
metadata:
name:nfs-pvc001
namespace:kube-ops
spec:
accessModes:
    -ReadWriteMany
resources:
    requests:
      storage:1Gi
storageClassName: manual-nfs-storage

4)Pod 挂载 PVC:

volumes:
- name: nfs-pv001
  persistentVolumeClaim:
    claimName: nfs-pvc001

📌 特点:

  • 更加规范,支持多 Pod 共享数据。

  • 管理上比直接挂载 NFS 要好。


6、使用 NFS-Subdir-External-Provisioner(动态卷)

nfs-subdir-external-provisioner 能在已有的 NFS 共享上按需动态创建子目录并把它包装成 PV,应用直接创建 PVC 即可得到 PV,不用手工预先创建 PV。适合:多租户、共享存储(ReadWriteMany)、希望对 NFS 自动化管理的场景。

步骤大致如下:

1)创建 ServiceAccount + RBAC 权限(确保能操作 PV、PVC、endpoints)。

2)部署 nfs-subdir-external-provisioner,指定 NFS 服务器和路径。

3)创建默认 StorageClass,让 PVC 自动使用它。

apiVersion: storage.k8s.io/v1
kind:StorageClass
metadata:
name:default-nfs-storageclass
annotations:
    storageclass.kubernetes.io/is-default-class:"true"# 如果你想设为默认类(可选)
provisioner:nfs-subdir-external-provisioner   # 必须和 Deployment 中的 PROVISIONER_NAME 一致
reclaimPolicy:Delete
volumeBindingMode:Immediate
# 可选 mountOptions
#mountOptions:
#  - vers=3
#  - noresvport

小建议:如果集群中还有其他 StorageClass,不要随意把它设为默认;生产环境中更常见的是显式在 PVC 中写 storageClassName。


4)定义 PVC 即可自动生成对应的 NFS 子目录。

pvc-test.yaml 示例:

apiVersion: v1
kind:PersistentVolumeClaim
metadata:
name:auto-pv-with-nfs-client-provisioner
namespace:default
spec:
storageClassName:default-nfs-storageclass
accessModes:
    -ReadWriteMany
resources:
    requests:
      storage: 1Mi

pod-test.yaml 示例:

apiVersion: v1
kind:Pod
metadata:
name:pod-touch-cfs
namespace:default
spec:
restartPolicy:Never
containers:
-name:test-pod
    image:busybox
    command: ["/bin/sh", "-c", "echo hello > /mnt/hello.txt && ls -la /mnt && sleep 300"]
    volumeMounts:
      -name:nfs-pvc
        mountPath:/mnt
volumes:
    -name:nfs-pvc
      persistentVolumeClaim:
        claimName: auto-pv-with-nfs-client-provisioner

📌 特点:

  • 真正的动态卷,无需手动创建 PV。

  • 非常适合多租户、多应用环境。

  • 管理性和扩展性最强,是生产推荐方案。


总结

在 Kubernetes 中,Volume 的使用场景大致可以这么选:

  • emptyDir → 临时缓存、日志目录。

  • hostPath → 调试环境快速挂载宿主机目录,不推荐生产使用。

  • local PV → 节点绑定存储,更规范的宿主机卷。

  • NFS 直接挂载 → 简单快速,但不够灵活。

  • NFS 静态 PV → 规范化持久化,支持多 Pod。

  • NFS 动态卷(推荐) → 自动管理,最适合生产环境。

一句话:测试用 emptyDir/hostPath,生产建议走 PV/PVC,最好结合 NFS 动态卷。