Skip to main content

Setup an NFS client provisioner in Kubernetes

Setup an NFS client provisioner in Kubernetes

One of the most common needs when deploying Kubernetes is the ability to use shared storage. While there are several options available, one of the most commons and easier to setup is to use an NFS server.
This post will explain how to setup a dynamic NFS client provisioner on Kubernetes, relying on an existing NFS server on your systems.

Step 1. Setup an NFS server (sample for CentOS)

First thing you will need, of course, is to have an NFS server. This can be easily achieved with some easy steps:

  • Install nfs package: yum install -y nfs-utils
  • Enable and start nfs service and rpcbind:
    systemctl enable rpcbind
    systemctl enable nfs-server
    systemctl start rpcbind
    systemctl start nfs-server

  • Create the directory that will be shared by NFS, and change the permissions:
    mkdir /var/nfsshare
    chmod -R 755 /var/nfsshare
    chown nfsnobody:nfsnobody /var/nfsshare

  •  Share the NFS directory over the network, creating the /etc/exports file:
    vi /etc/exports
    /var/nfsshare * (rw,sync,no_root_squash,no_all_squash)
  • Restart the nfs service to apply the content:
    systemctl restart nfs-server
  • Add NFS and rpcbind services to firewall:
    firewall-cmd --permanent --zone=public --add-service=nfs
    firewall-cmd --permanent --zone=public --add-service=rpcbind
    firewall-cmd --reload

    The NFS server is now ready to be used

Step 2. Install NFS client provisioner

To achieve that, we will rely on Kubernetes external storage provisioner ( . An external provisioner is a dynamic volume provisioner, whose code lives outside kubernetes code.
It relies on an StorageClass object, that defines the external provisioner instance. Then, that instance will wait for PersistentVolumeClaims asking for that specific StorageClass, and will automatically create PersistentVolumes.
In that case we are relying on NFS-client provisioner ( , that will provide those volumes, relying on an existing NFS server.

In order to use that, several steps are needed:
  • Clone the external-storage repository and switch to the nfs-client folder:
    git clone
    cd external-storage/nfs-client
  • Customize the deploy/class.yaml file, to give a custom provisioner name to your instance:
    kind: StorageClass
      name: managed-nfs-storage
    provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
      archiveOnDelete: "false"
  • Customize the deploy/deployment.yaml file, to specify the location and folder for your NFS server, and to give the right provisioner name:
    kind: ServiceAccount
      name: nfs-client-provisioner
    kind: Deployment
    apiVersion: extensions/v1beta1
      name: nfs-client-provisioner
      replicas: 1
        type: Recreate
          app: nfs-client-provisioner
         serviceAccountName: nfs-client-provisioner
           - name: nfs-client-provisioner
               - name: nfs-client-root
                 mountPath: /persistentvolumes
               - name: PROVISIONER_NAME
                 value: fuseim.pri/ifs
    # or choose another name, must match
               - name: NFS_SERVER
                 value: <<IP_OF_YOUR_NFS_SERVER>>
               - name: NFS_PATH
                 value: <<PATH_TO_NFS_SHARED_FOLDER>>
           - name: nfs-client-root
               server: <<IP_OF_YOUR_NFS_SERVER>>
               path: <<PATH_TO_NFS_SHARED_FOLDER>>
               apiVersion: v1
  • Create the objects into your kubernetes cluster:
    kubectl create -f deploy/rbac.yaml
    kubectl create -f deploy/class.yaml
    kubectl create -f deploy/deployment.yaml
  • To actually start testing the system, you will need to create a PersistentVolumeClaim using that StorageClass. Then you will need to create a pod that uses this PersistentVolumeClaim:
    kind: PersistentVolumeClaim
    apiVersion: v1
      name: test-claim
      annotations: "managed-nfs-storage"
        - ReadWriteMany
          storage: 1Mi

    kind: Pod

    apiVersion: v1
      name: test-pod
       - name: test-pod
           - "/bin/sh"
           - "-c"
           - "touch /mnt/SUCCESS && exit 0 || exit 1"
           - name: nfs-pvc
             mountPath: "/mnt"
    restartPolicy: "Never"
       - name: nfs-pvc
           claimName: test-claim

    kubectl create -f deploy/claim.yaml
    kubectl create -f deploy/pod.yaml
    You can see that the pods can be started now with NFS volumes that are dynamically provisioned, relying on your existing NFS server installation.


Post a Comment

Popular posts from this blog

How to deploy TripleO Queens without external network

TripleO Queens has an interesting feature that is called 'composable networks'. It allows to deploy Openstack with the choice of networks that you want, depending on your environment. Please see:

By default, the following networks are defined:
StorageStorage ManagementInternal ApiTenantManagementExternal The external network allows to reach the endpoints externally, and also to define networks to reach the vms externally as well. But to have that, it is needed to have a network with external access, routable, on your lab. Not all labs have it, specially for CI environments, so it may be useful to deploy without it, and just have internal access to endpoints and vms. In this blogpost i'm just going to explain how to achieve it.

First make a copy of your original tripleo-heat-templates, to another directory /home/stack/working-templates, and edit the following files:

Build and use security hardened images with TripleO

Starting to apply since Pike Concept of security hardened images Normally the images used for overcloud deployment in TripleO are not security hardened. It means, the images lack all the extra security measures needed to accomplish with ANSSI requirements. These extra measures are needed to deploy TripleO in environments where security is an important feature.
The following recommendations are given to accomplish with security guidelines:
ensure that /tmp is mounted on a separate volume or partition, and that it is mounted with rw,nosuid,nodev,noexec,relatime flagsensure that /var, /var/log and /var/log/audit are mounted on separates volumes or partitions, and that are mounted with rw,relatime flags.ensure that /home is mounted on a separate partition or volume, and that it is mounted with rw,nodev,relatime flags.include extra kernel boot flag to enable auditing: add audit=1 to GRUB_CMDLINE_LINUX settingdisable kernel support for USB via bootloader configuration: add nousb to GRUB_CMD…