Kubernetes Storage – Part 1 – NFS complete tutorial

      In this series of articles, I will discuss available Kubernetes storage solutions with the complete manual for deploying them to/for Kubernetes. This series of tutorials is helpful for everyone who knows the Kubernetes storage architecture and concepts and wants to deploy storage for Stateful applications in Kubernetes.

      Follow our social media:





      Resource Requirements:

      • A running Kubernetes cluster. 1.18+ is suggested.
      • A running node with some available storage.

      I will run the steps on Ubuntu-based systems. I suggest you do so.

      For this demonstration, I use two nodes with the following configuration:

      A running node used as the NFS server:

      OS: Ubuntu 20.04
      FQDN: node004.b9tcluster.local
      IP Address:

      A single-node Kubernetes cluster:

      OS: Ubuntu 20.04
      Kubernetes: 1.21.5 (k3s distribution)
      FQDN: node005.b9tcluster.local
      IP Address:

      1- Deploy and configure NFS server:

      Run the following commands on the node you considered for the NFS server. You can deploy a clustered NFS server with high availability support.

      apt update && apt -y upgrade
      apt install -y nfs-server
      mkdir /data
      cat <<EOF >> /etc/exports
      systemctl enable --now nfs-server
      exportfs -ar

      These commands install NFS server and export /data , which is accessible by the Kubernetes cluster. In the case of a multi-node Kubernetes cluster, you should allow all Kubernetes worker nodes.

      2- Prepare Kubernetes worker nodes:

      Now, to connect to the NFS server, the Kubernetes nodes need the NFS client package. You should run the following command only on the Kubernetes worker nodes – and control-plane nodes if they act as workers too.

      apt install -y nfs-common

      Important tip! Each storage solution may need client packages to connect to the storage server. You should install them in all Kubernetes worker nodes.

      For NFS, the nfs-common package is required.

      3- Using NFS in Kubernetes:

      Method 1 ā€” Connecting to NFS directly with Pod manifest:

      To connect to the NFS storage directly using the Pod manifest, use the NFSVolumeSource in the PodSpec. Here is an example:

      apiVersion: v1
      kind: Pod
        name: test
          app.kubernetes.io/name: alpine
          app.kubernetes.io/part-of: kubernetes-complete-reference
          app.kubernetes.io/created-by: ssbostan
          - name: alpine
            image: alpine:latest
              - touch
              - /data/test
              - name: nfs-volume
                mountPath: /data
          - name: nfs-volume
              server: node004.b9tcluster.local
              path: /data
              readOnly: no

      Method 2 ā€” Connecting using the PersistentVolume resource:

      Use the following manifest to create the PersistentVolume object for the NFS volume. You should note that the storage size does not take any effect.

      apiVersion: v1
      kind: PersistentVolume
        name: nfs-volume
          storage.k8s.io/name: nfs
          storage.k8s.io/part-of: kubernetes-complete-reference
          storage.k8s.io/created-by: ssbostan
          - ReadWriteOnce
          - ReadOnlyMany
          - ReadWriteMany
          storage: 10Gi
        storageClassName: ""
        persistentVolumeReclaimPolicy: Recycle
        volumeMode: Filesystem
          server: node004.b9tcluster.local
          path: /data
          readOnly: no

      Method 3 ā€” Dynamic provisioning using StorageClass:

      You must install the NFS provisioner to provision PersistentVolume dynamically using StorageClasses. I use the nfs-subdir-external-provisioner to achieve this. The following commands install everything we need using the Helm package manager.

      helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
      helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
        --create-namespace \
        --namespace nfs-provisioner \
        --set nfs.server=node004.b9tcluster.local \
        --set nfs.path=/data

      To create the PersistentVolumeClaim, use the following manifest:

      apiVersion: v1
      kind: PersistentVolumeClaim
        name: nfs-test
          storage.k8s.io/name: nfs
          storage.k8s.io/part-of: kubernetes-complete-reference
          storage.k8s.io/created-by: ssbostan
          - ReadWriteMany
        storageClassName: nfs-client
            storage: 1Gi

      4- Kubernetes and NFS storage specification:

      NFS has the following specifications in the Kubernetes world. It would help to consider them before using the NFS storage in production.

      • ReadWriteOnce, ReadOnlyMany, and ReadWriteMany access modes.
      • The storage size does not take any effect!
      • In the case of dynamic provisioning, volumes are separated into different directories but without access controls or proper isolation.

      If you like this series of articles, please share them and write your thoughts as comments here. Your feedback encourages me to complete this massively planned program.

      Follow my LinkedIn https://www.linkedin.com/in/ssbostan

      Follow Kubedemy LinkedIn https://www.linkedin.com/company/kubedemy

      Follow Kubedemy Telegram https://telegram.me/kubedemy

      Hi, Iā€™m Saeid Bostandoust

      Leave a Reply

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