Going back to the end of the previous sub-chapter, we introduce the Rook storage provider. It is inserted between the hard disk of the VMs, always based on NFS, and the Kubernetes cluster. As said previously, NFS allows remote hosts to mount filesystems over a network and interact with those filesystems as though they are mounted locally. This enables system administrators to consolidate resources onto centralized servers on the network. As a prerequisite, NFS client packages must be installed on all nodes (nfs-utils on CentOS), where Kubernetes might run pods with NFS mounted.

Deploy NFS Operator

First deploy the Rook NFS operator using the following commands

# Clone the repository and enter the directory that we will use throughout the guide
$ git clone --single-branch --branch v1.5.3 https://github.com/rook/rook.git
$ cd rook/cluster/examples/kubernetes/nfs

# Then launch (operator is created in the "rook-nfs-system" namespace)
$ kubectl create -f common.yaml -f operator.yaml

# Check if the operator is up and running
$ kubectl get pod -n rook-nfs-system
NAME                                READY   STATUS    RESTARTS   AGE
rook-nfs-operator-f79889845-8r5kq   1/1     Running   0          11m

Some preliminary steps

It is recommended that you create Pod Security Policies first. To do this, you can use the psp.yaml file already present in the folder with the usual command

$ kubectl create -f psp.yaml
podsecuritypolicy.policy/rook-nfs-policy created

# To get it
$ kubectl get psp
NAME              PRIV   CAPS                           SELINUX    RUNASUSER   FSGROUP    SUPGROUP   READONLYROOTFS   VOLUMES
rook-nfs-policy   true   DAC_READ_SEARCH,SYS_RESOURCE   RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            configMap,downwardAPI,emptyDir,persistentVolumeClaim,secret,hostPath

Before we create NFS Server we need to create ServiceAccount and RBAC rules

$ kubectl create -f rbac.yaml
namespace/rook-nfs created
serviceaccount/rook-nfs-server created
clusterrole.rbac.authorization.k8s.io/rook-nfs-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/rook-nfs-provisioner-runner created

In this example will walk through creating a NFS Server instance, that exports storage that is backed by the default StorageClass (SC) for the environment you happen to be running in. In some environments, this could be a hostPath, in others it could be a cloud provider virtual disk. Either way, this example requires a default SC to exist.

So let's create a simple SC (remember to activate the plugin --enable-admission-plugins=DefaultStorageClass in kube-apiserver.yaml), which will act as the default

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

Next we create a "large" PV (without exaggerating) of type hostPath, based on the default SC

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv
  labels:
    type: local
spec:
  storageClassName: local-storage	# Same as the name of the default SC created
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/mnt/data"	# The "data" folder, if it does not exist, will be created automatically on the node where the NFS Server pod is up and running.

Create and Initialize NFS Server

Now that the operator is running, we can set up an instance of a NFS Server, creating an instance of the nfsservers.nfs.rook.io resource. The various fields and options of the NFS Server resource can be used to configure the server and its volumes to export. With the nfs.yaml file, now create the NFS Server as shown

$ kubectl create -f nfs.yaml
persistentvolumeclaim/nfs-default-claim created
nfsserver.nfs.rook.io/rook-nfs created

We can verify that a Kubernetes object has been created, that represents our new NFS Server and its export with the command

$ kubectl get nfsservers.nfs.rook.io -n rook-nfs
NAME       AGE   STATE
rook-nfs   40m   Running

Verify, afterwards, that the NFS Server pod is up and running. If the NFS Server pod is in the Running state, then we have successfully created an exported NFS share, that clients can start to access over the network.

$ kubectl get pod -l app=rook-nfs -n rook-nfs
NAME         READY   STATUS    RESTARTS   AGE
rook-nfs-0   2/2     Running   0          43m

Accessing the Export

Since Rook version v1.0, Rook supports dynamic provisioning of NFS. This example will be showing how dynamic provisioning feature can be used for NFS. Once the NFS Operator and an instance of NFS Server is deployed, a SC similar to sc.yaml has to be created to dynamically provisioning volumes

$ k create -f sc.yaml
storageclass.storage.k8s.io/rook-nfs-share1 created


The SC need to have the following 3 parameters passed:

  • exportName: it tells the provisioner which export to use for provisioning the volumes;
  • nfsServerName: name of the NFS Server instance;
  • nfsServerNamespace: namespace where the NFS Server instance is running.

Once you have created the SC above, you can create a PVC that references it. The PVC will automatically (dynamically) create the respective PV.

$ k create -f pvc.yaml
persistentvolumeclaim/rook-nfs-pv-claim created