Skip to content

NFS Persistent Storage for Kubernetes

References

Introduction

Kubernetes is an incredible vehicle for automated deployment and management of containerized workloads. While the workloads are ephemeral, persistent storage is required to gain any real value from the applications deployed.

Kubernetes doesn't include any persistent storage other than a very basic local node storage called 'hostpath'. This is fine for a single node test or development environment, but for multi-node clusters or for production environments, an external persistent storage system is required.

Manual NFS PV Provisioning

An NFS server provides a good solution for persistent storage for a homelab kubernetes cluster. Other than an available NFS server (such as a local network NAS for example) the only other requirement is to have NFS client support available on the cluster node hosts. Once these requirements are satisfied, it is a relatively simple task to create NFS backed persistent storage to be used by a deployed application.

Manual NFS PV

The simplest way to make use of a local NFS server for persistent storage is the manual method. First you create the storage directory in an appropriate location in the NFS share. Then you create a PV (Persistent Volume) object that references your NFS server and the specified storage directory.

$ cat delinit_pv.yml

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: delinit-pv
  labels:
    name: delinit-pv
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  mountOptions:
    - hard
    - nfsvers=4.0
  nfs:
    server: 192.168.20.11
    path: "/volume1/k8s-storage/delfax/delinit"

# EOF

Manual NFS PVC

The next step is to create a PVC (Persistent Volume Claim) object that binds to the previously created PV object. The PVC object provides the link to the persistent storage for the application.

$ cat delinit_pvc.yml

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: delinit-pvc
  labels:
    app: delinit
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: "manual"
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      name: delinit-pv

# EOF

The PVC object is then referenced in the application deployment manifest.

$ cat delinit_deployment.yml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: delinit
spec:
  selector:
    matchLabels:
      app: delinit
  replicas: 1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: delinit
    spec:
      containers:
        - name: delinit
          image: nginx
          ports:
            - containerPort: 80
              name: "delinit"
          volumeMounts:
            - name: delinit
              mountPath: "/usr/share/nginx/html"
      volumes:
        - name: delinit
          persistentVolumeClaim:
            claimName: delinit-pvc

# EOF

Automatic NFS PV Provisioning

There are currently two external NFS provisioners. The one I use is the NFS Subdir External Provisioner, linked in the references section. How I've deployed it to my homelab is also linked in the references section.

Automatic NFS PVC

Once the NFS provisioner has been successfully deployed to the cluster, it is quite easy to make use of it for creation of persistent storage for deployed applications. The following is an example of a PVC manifest that will create a storage object which can then be referenced in an application deployment manifest.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
#  annotations:
#    nfs.io/storage-path: "test-path" # not required, depending on whether this annotation was shown in the storage class description
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

# EOF

Created: 2023-04-18 17:42
Last update: 2023-04-19 20:43