在 Kubernetes 里动态挂载 NFS,核心是部署一个 NFS Client Provisioner 并配置对应的 StorageClass,让 PVC 能自动创建 PV 指向 NFS 路径。
先说结论:通过 StorageClass 对接 nfs-subdir-external-provisioner 是实现动态挂载的标准做法,适合需要按需分配子目录的场景。
- 适合:多租户需要隔离存储目录,或不想手动管理 PV 生命周期。
- 先准备:确保集群节点能网络通达 NFS 服务器,且权限配置正确。
- 验收:PVC 状态变为 Bound,且 Pod 内可读写文件。
命令速用版
# 部署 NFS Client Provisioner (示例使用 Helm)
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \`--set` nfs.server=<NFS_SERVER_IP> \`--set` nfs.path=<NFS_SERVER_PATH> \`--set` storageClass.name=nfs-client \`--set` storageClass.defaultClass=true为什么会这样
PVC 本身只是存储请求,它不知道底层是 NFS 还是云盘。StorageClass 充当了“中介”,告诉 Kubernetes 当有人申请 PVC 时,调用哪个 Provisioner 去创建实际的存储卷。对于 NFS 而言,原生 Kubernetes 不支持直接动态创建 NFS 子目录,所以需要额外的 nfs-subdir-external-provisioner 组件来监听 PVC 事件,并在 NFS 服务器上创建对应文件夹,再绑定给 PV。
分步处理
1. 确认 NFS 服务可用
在任意集群节点上执行 mount 测试,确保网络和权限没问题。
showmount -e <NFS_SERVER_IP>
mkdir /tmp/test-nfs
mount -t nfs <NFS_SERVER_IP>:<PATH> /tmp/test-nfs
touch /tmp/test-nfs/write_test
umount /tmp/test-nfs2. 部署 Provisioner
可以使用 Helm 或直接 apply YAML。关键是指对 NFS 服务器地址和路径。注意 serviceAccount 需要足够权限创建 PV。
3. 创建 PVC
指定 storageClassName 与 Provisioner 配置一致。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nfs-dynamic-pvc
spec:accessModes:- ReadWriteManystorageClassName: nfs-clientresources:requests:storage: 1Gi4. 创建 Pod 挂载
在 volumes 中引用该 PVC。
怎么验证是否生效
执行 kubectl get pvc nfs-dynamic-pvc,STATUS 列应显示 Bound。进入 Pod 内部尝试写入文件,同时观察 NFS 服务器对应路径下是否生成了以 namespace-claim-name-uuid 命名的子目录。
常见坑
权限拒绝(Permission denied):NFS 服务器通常默认开启 root_squash,导致容器内 root 用户映射为 nfsnobody。建议在 Provisioner 配置中调整 gid/uid 或在 NFS 服务端调整 export 选项。
StorageClass 不匹配:如果 PVC 没写 storageClassName,会使用集群默认的。如果 Provisioner 设置的默认类被覆盖,PVC 会一直 Pending。
网络策略限制:如果集群启用了 NetworkPolicy,确保 Provisioner Pod 能访问 NFS 服务器的 2049 端口。
参考来源
- Kubernetes 官方文档 - StorageClasses: https://kubernetes.io/docs/concepts/storage/storageclasses/
- Kubernetes SIGs - nfs-subdir-external-provisioner: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
原文链接:https://www.zjcp.cc/ask/10329.html
