Changing the Default Storage Class to NFS¶
By default, K3s installs the local-path storage class as default
. This makes sense for simple or single-node setups but is often insufficient for multi-node clusters or when you need persistent volumes backed by network storage. Below, we’ll disable the local-path default and install the NFS subdir external provisioner so that new PersistentVolumeClaims (PVCs) are automatically created on an NFS server.
1. Patch the Existing Local-Path Storage Class¶
We want to ensure that local-path no longer claims the role of “default” storage class. Once patched, you can still use local-path volumes explicitly, but new PVCs without a specified storage class will be allocated from the NFS-based default.
Run the following command to patch the local-path storage class:
kubectl patch storageclass local-path \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
- This removes the “default class” annotation from local-path.
- Verify the patch by running:
You should see something like:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ...
local-path rancher.io/local-path Delete WaitForFirstConsumer ...
Notice there is no (default)
next to local-path
anymore.
2. Install the NFS Subdir External Provisioner¶
The NFS subdir external provisioner is a lightweight way to dynamically create subdirectories on an existing NFS share for each PVC. It can be designated as your new default storage class.
-
Identify Your NFS Server and Path
- Suppose you can mount NFS like this:
Then: -
nfs_server
is44.223.98.19
-nfs_path
is/nfs1
-
Add the Helm Repository and Create a New Namespace
-
Install the NFS Subdir External Provisioner
Run the following Helm install command, ensuring you enable default storage class:helm install nfs-subdir-external-provisioner \ nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ --namespace nfs-storage \ --set nfs.server=$nfs_server \ --set nfs.path=$nfs_path \ --set storageClass.defaultClass=true
--set nfs.server
: The IP or hostname of your NFS server.--set nfs.path
: The base directory on the NFS server where subdirectories will be created.--set storageClass.defaultClass=true
: Tells the provisioner to mark its storage class as default.
-
Confirm the New Default Class
You should now see something like:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path rancher.io/local-path Delete WaitForFirstConsumer false 42m nfs-client (default) cluster.local/nfs-subdir-external-provisioner Delete Immediate true 7s
With nfs-subdir-external-provisioner flagged as (default).
3. Verify Dynamic Provisioning on NFS¶
-
Create a Test PVC without specifying a storage class:
Create a file called
pvc-test.yaml
and paste the following content: -
Check the PVC and Bound PV:
The status should transition to
Bound
. A PersistentVolume will be automatically created, and a matching directory appears in your NFS share (/nfs1/
). -
Inspect the Storage Class:
The
Events:
section should show the storage has been successfully provisioned. Example:Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ExternalProvisioning 27s (x2 over 27s) persistentvolume-controller Waiting for a volume to be created either by the external provisioner 'cluster.local/nfs-subdir-external-provisioner' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered. Normal Provisioning 27s cluster.local/nfs-subdir-external-provisioner_nfs-subdir-external-provisioner-587d45f4c4-m54p4_583f726b-870b-4a18-b56e-706887870854 External provisioner is provisioning volume for claim "default/test-pvc" Normal ProvisioningSucceeded 27s cluster.local/nfs-subdir-external-provisioner_nfs-subdir-external-provisioner-587d45f4c4-m54p4_583f726b-870b-4a18-b56e-706887870854 Successfully provisioned volume pvc-c6648e6f-0861-4d51-acac-4a16262fc17d
4. Remove the Test NFS PVC¶
To clean up and remove the test PVC and associated PersistentVolume (PV) after verifying the NFS storage class, follow these steps:
-
Delete the test-pvc PersistentVolumeClaim (PVC) using the kubectl delete command:
This will automatically delete the associated PersistentVolume (PV) created by the NFS storage class.
-
Verify PVC and PV Deletion
Check that the PVC and PV have been successfully deleted:
Both the test-pvc PVC and its associated PV should no longer appear in the output.
-
Delete the test-pvc.yaml file
If you no longer need the pvc-test.yaml file, you can remove it:
4. Conclusion¶
By patching the existing local-path
storage class to not be the default and installing the NFS subdir external provisioner with --set storageClass.defaultClass=true
, you’ve now made NFS the default storage class in your K3s cluster. Any new PVCs without an explicit storageClassName
will automatically be provisioned on your remote NFS server, allowing multiple nodes in your cluster to share data seamlessly.
If you still need local-path volumes for specialized workloads, you can specify storageClassName: local-path
in a given PVC. Otherwise, your cluster now defaults to NFS.