需部署NFS服务器并配置共享目录,安装客户端工具,验证showmount响应;再创建ServiceAccount、ClusterRole等RBAC资源,部署nfs-subdir-external-provisioner,最后定义StorageClass并确保provisioner名称严格匹配,方可实现PVC自动绑定PV。

在Kubernetes集群中为应用快速提供NFS后端的持久化存储,避免每次创建PVC都手动写PV YAML、反复检查路径和权限、绑定失败后Pod卡在Pending状态——你需要一套能自动响应PVC请求并生成PV的StorageClass机制。
准备NFS服务器与客户端环境
这一步不是可选动作,而是整个动态供给链路的物理基础。没有可用的NFS共享目录,后续所有YAML都会因挂载失败而静默报错。
在NFS服务端(例如IP为192.168.85.100的节点)执行:
mkdir -pv /nfs/data && chmod 777 -R /nfs/data && echo "/nfs/data *(insecure,rw,sync,no_root_squash)" > /etc/exports && exportfs -r && systemctl restart nfs-server rpcbind
在Kubernetes所有Worker节点(含Master,如果它也参与调度)安装客户端工具:
yum install -y nfs-utils(CentOS/RHEL)或 apt-get install -y nfs-common(Ubuntu/Debian)
【必须验证】在任一Worker节点执行 showmount -e 192.168.85.100,输出应包含 /nfs/data。若无响应,请先排查防火墙(rpcbind默认用111端口,NFS主要用2049)、网络连通性及exports语法错误——这里卡住,后面全白搭。
部署nfs-subdir-external-provisioner
官方已将nfs-client-provisioner迁移至kubernetes-sigs组织,镜像地址为:k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2(国内可替换为 registry.cn-hangzhou.aliyuncs.com/google_containers/nfs-subdir-external-provisioner:v4.0.2)
创建ServiceAccount、ClusterRole、ClusterRoleBinding三件套,赋予provisioner操作PV/PVC/StorageClass的最小必要权限;缺一不可,否则Deployment启动后会持续报错“no permission to create persistentvolumes”。
编写Deployment资源清单,关键字段必须严格匹配:
• env中PROVISIONER_NAME值(如example.com/nfs)需与后续StorageClass的provisioner字段完全一致
• volumes.nfs.server和volumes.nfs.path必须指向你上一步验证成功的NFS地址与共享路径
• volumeMounts.mountPath必须为/persistentvolumes,这是provisioner内部硬编码的根挂载点
创建StorageClass对象
方法一:基础版(支持扩容)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: example.com/nfs
parameters:
archiveOnDelete: "false"
reclaimPolicy: Delete
allowVolumeExpansion: true
方法二:生产加固版(推荐)
在parameters下追加:
onDelete: "delete"
onFailure: "retry"
并显式声明volumeBindingMode: Immediate(默认值,但写明更清晰)
注意:StorageClass是集群级资源,无需指定namespace;但它的provisioner名称必须与Deployment中env.PROVISIONER_NAME一字不差,大小写敏感,多一个空格就无法触发自动创建。
验证动态供给是否生效
第一步:创建测试PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs-client
第二步:观察资源状态
kubectl get pvc → 状态应从Pending变为Bound
kubectl get pv → 自动出现一条新PV,NAME字段以“pvc-”开头,STATUS为Bound,CAPACITY与PVC请求一致,STORAGECLASS显示nfs-client
第三步:确认NFS服务端真实生成子目录
登录NFS服务器,执行 ls -l /nfs/data/,应看到类似default-test-pvc-pvc-xxxxxx的随机命名目录,且属主为nobody:nogroup(由no_root_squash保证)
第四步:用临时Pod挂载验证读写
kubectl run test-pod --image=busybox:1.35 --rm -it --restart=Never --command -- sh -c "echo 'hello' > /mnt/test.txt && cat /mnt/test.txt" --volume=test-vol --volume-mounts=mountPath=/mnt,vol=test-vol,pvc=test-pvc


















