I’ve been running Kubernetes backed by NFS persistent volumes for a long time now and one of the rough edges for me has be the creation of persistent volumes(pv) and their claims(pvc). It involves me sshing to my NFS server, creating a directory for the share, creating yaml for the pv/pvc, and then finally applying these to the cluster. This was arduous, but I passed it off as acceptable since it wasn’t too often I was deploying new workloads. This process needed some help and while Kubernetes has supported default storage classes for a while, I didn’t take the time to learn how to use it or how to setup NFS to use it. I should have and hopefully I can help you as well.
Potentially Boring Details
To get your storage requests in your workloads to automagically get space off your NFS server requires a few things. First, you have to setup your NFS server. Then you have to run a workload on Kubernetes to support the NFS provisioning. This is due to Kubernetes not having NFS support internally and may or may not change in the future. Finally you have to tell your Kubernetes cluster to use this NFS provisioner for storage requests. The list of Kubernetes default providers is here. This is all easier to do than to say, so let’s get to it.
First off, we’re going to get a Kubernetes cluster up. The easiest way is to use conjure-up. Run:
sudo snap install conjure-up --classic
or on MacOS:
brew install conjure-up
And follow that up with:
Select your addons, cloud, and a few other things and you’re off.
A few minutes later, you’re ready to move on to deploying an NFS server. Luckily this is an easy process with juju and the nfs charm. Note the constraint in order to request a larger disk.
juju deploy nfs --constraints root-disk=30G
Now we need to relate the nfs charm to the kubernetes worker charm:
juju relate nfs kubernetes-worker
That is it. You now have setup your Kubernetes cluster to hand out persistent volumes. You can verify that things are working by checking the storage classes on the cluster:
kubectl get sc
NAME PROVISIONER AGE
default (default) fuseim.pri/ifs 1h
Note the (default) indicating that this provisioner is the default one. Further, we can add a persistent volume and verify that it gets bound and allocated.
$ kubectl apply -f - <<EOF
EOF$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-1af0c73b-6f58-11e8-bade-0a8bc3df5930 1Gi RWX Delete Bound default/test default 8s
That is it. Now you no longer have to ssh to your NFS server or manually create persistent volumes. Hopefully this guide has helped you see how easy it is to use a default provisioner, especially with conjure-up, juju, and the Canonical Distribution of Kubernetes. Be sure to clap if this was useful to you to encourage me to continue to write these guides!