How to Deploy NFS Subdir External Provisioner on Kubernetes with HA
This guide walks through deploying the NFS‑subdir‑external‑provisioner on Kubernetes, covering migration to the new repository, configuring storage classes with subdirectory support, applying RBAC resources, creating PVCs, enabling high‑availability with leader election, and troubleshooting common mount errors.
Background
NFS is a common volume storage option in Kubernetes, but the original nfs-client-provisioner repository has been archived. The maintained fork at
https://github.com/lorenzofaresin/nfs-subdir-external-provisioneradds a pathPattern parameter that allows per‑PVC subdirectory configuration.
Deploying the Provisioner
Create the required YAML files (StorageClass, Deployment, RBAC) and adjust the NFS server IP and path to match your environment.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "false" apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: kube-system
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 172.16.33.4
- name: NFS_PATH
value: /
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
volumes:
- name: nfs-client-root
nfs:
server: 172.16.33.4
path: / apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get","list","watch","create","delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get","list","watch","update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create","update","patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get","list","watch","create","update","patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.ioNote: If the image cannot be pulled, pull it from an external machine and import it. RBAC usually does not need changes; adjust class.yaml when configuring subdirectories.
Apply all resources:
kubectl apply -f class.yaml -f deployment.yaml -f rbac.yamlCreating a PVC
Example PVC that uses the storage class:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-pvc-2
namespace: nacos
spec:
storageClassName: "managed-nfs-storage"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10GiAfter creating a StatefulSet that mounts this PVC, Kubernetes automatically creates a corresponding PV and binds it.
Configuring Subdirectories
Update class.yaml to add the pathPattern parameter, then recreate the StorageClass.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "false"
pathPattern: "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}"Create a PVC with the annotation that defines the subdirectory:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-pvc-2
namespace: nacos
annotations:
nfs.io/storage-path: "test-path-two"
spec:
storageClassName: "managed-nfs-storage"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100MiApply the resources and verify that the NFS server now contains a directory structure like /data/nfs/nacos/test-path-two, confirming the subdirectory logic works.
Provisioner High Availability
For production, run three replicas and enable leader election:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: kube-system
spec:
replicas: 3
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: www.ayunw.cn/nfs-subdir-external-provisioner:v4.0.2-31-gcb203b4
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: ENABLE_LEADER_ELECTION
value: "True"
- name: NFS_SERVER
value: 172.16.33.4
- name: NFS_PATH
value: /
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
volumes:
- name: nfs-client-root
nfs:
server: 172.16.33.4
path: /Re‑apply the updated class and deployment, then check that three pods are running and one has acquired the leader lease, confirming HA is active.
Troubleshooting
If pods fail to mount the NFS volume, the typical cause is a missing NFS client on the node. Install it with:
yum install -y nfs-utils # or apt-get install nfs-commonAfter installing the client, the mount succeeds.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
