Kubernetes: Persistent Storage using NFS-client-provisioner.

In this post, I will be demonstrating how to use NFS-client as a provisioner. The NFS client provisioner is an automatic provisioner that leverages your existing NFS server to create persistent volumes. In this setup, we have one Master,one worker node and the NFS node.

Requirement:
NFS-server
Kubernetes Cluster.

How to Setup NFS-server:
On the NFS node, perform the following steps.

sudo apt update
sudo apt upgrade -y

next we install the NFS-kernel-server

sudo apt install nfs-kernel-server -y
sudo mkdir /var/nfs/general -p

next we change the ownership and group on the directory

sudo chown nobody:nogroup /var/nfs/general

next we will edit the file /etc/exports and add the lines that follows.

/var/nfs/general     x.x.x.x(rw,sync,no_subtree_check) y.y.y.y(rw,sync,no_subtree_check)

The x and y represents the IP address of the servers that will be accessing the NFS-server.

next we restart the NFS server

sudo systemctl restart nfs-kernel-server

for each node that requires access to the NFS node we need to install NFS Common.

sudo apt install nfs-common

At this point we have completed the setup of our nfs node for two nodes to access.
next we deploy NFS-client into our Kubernetes cluster.

Requirement:
nfs-deploy.yaml #install the nfs client
nfs-serviceaccount.yaml #create SA for nfs-client
nfs-class.yaml #creates storage class for nfs-client purposes
nfs-clusterrole.yaml #create cluster role for nfs client
nfs-clusterrolebind.yaml #create cluster role binding for nfs-client
test-claim.yaml #configuration to test that we can now dynamically provision persistent volumes.

we will create a directory called nfs-client for the following files

mkdir nfs-client
cd nfs-client

next create these files.

nfs-deploy.yaml

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 
            - name: NFS_PATH
              value: /var/nfs/general
      volumes:
        - name: nfs-client-root
          nfs:
            server: 
            path: /var/nfs/general

nfs-serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner

nfs-class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: fuseim.pri/ifs

nfs-clusterrole.yaml

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - 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: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

nfs-clusterrolebind.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

test-claim.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

The value for PROVISIONER_NAME in the nfs-deploy.yaml must be the same as the one in nfs-class.yaml.

kubectl create -f  nfs-client/

On the NFS server, verify that the file was written to the /var/nfs/general path

Leave a Reply

Your email address will not be published. Required fields are marked *