๐Ÿท๏ธ Implement storage classes and dynamic volume provisioning

๐Ÿท๏ธ Implement storage classes and dynamic volume provisioning#

StorageClasses

StorageClasses simplify and automate the process of provisioning and managing storage resources, provide users with the flexibility to choose appropriate storage types for their workloads, and help administrators enforce policies and manage storage infrastructure more effectively.
StorageClasses enables dynamic provisioning of storage resources. Without StorageClasses, administrators have to manually create PersistentVolumes (PVs) for each PersistentVolumeClaim (PVC) made by users. With StorageClasses, this process is automated. When a user creates a PVC and specifies a StorageClasses, the system automatically creates a corresponding PV that meets the requirements.

NFS provisioner#

Tip

Configure an NFS volume.

On a VM (not a clusterโ€™s node).

แ… sudo mkdir /opt/guisam-nfs
แ… sudo chmod 1777 /opt/guisam-nfs
แ… sudo bash -c 'echo hello world > /opt/guisam-nfs/hello.txt'
แ… sudo apt update && sudo apt install nfs-kernel-server -y
แ… sudo systemctl status nfs-server.service
แ… sudo vi /etc/exports
แ… grep -v "^#.*$\|^$" /etc/exports
/opt/guisam-nfs/ *(rw,sync,no_root_squash,subtree_check)
แ… sudo exportfs -ra

On control-plane cp-01.

แ… sudo apt install nfs-common
แ… showmount -e 192.168.94.61
Export list for 192.168.94.61:
/opt/guisam-nfs *
แ… sudo mount 192.168.94.61:/opt/guisam-nfs /mnt
แ… mount | grep guisam
192.168.94.61:/opt/guisam-nfs on /mnt type nfs4 (rw,relatime,vers=4.2,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.94.73,local_lock=none,addr=192.168.94.61)
แ… sudo umount /mnt
แ… helm repo add nfs-subdir-external-provisioner \
https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
แ… helm search repo nfs-subdir-external-provisioner
แ… helm install nfs-provisioner \
nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=forge \
--set nfs.path=/opt/guisam-nfs

local-path provisioner#

k apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.32/deploy/local-path-storage.yaml

check existing storageclasses#

แ… k get sc
NAME         PROVISIONER                                                     RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-path   rancher.io/local-path                                           Delete          WaitForFirstConsumer   false                  6m16s
nfs-client   cluster.local/nfs-provisioner-nfs-subdir-external-provisioner   Delete          Immediate              true                   25s

usage#

แ… cat <<EOF | k apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-guisam
  labels:
    storage: nfs-guisam
spec:
  storageClassName: nfs-client
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
EOF
แ… k create deploy guisamweb \
--dry-run=client --image=nginx:alpine \
--replicas=2 --port=80 \
-o yaml > guisamweb.yaml
แ… diff -u guisamweb.yaml.before guisamweb.yaml
--- guisamweb.yaml.before       2025-12-09 15:55:53.478109773 +0100
+++ guisamweb.yaml      2025-12-09 15:55:41.853154996 +0100
@@ -15,10 +15,28 @@
       labels:
         app: guisamweb
     spec:
+      initContainers:
+      - image: bash
+        name: bash
+        command:
+        - sh
+        - -c
+        - "echo 'GuiSam was here!' > /usr/share/nginx/html/index.html"
+        resources: {}
+        volumeMounts:
+        - name: html
+          mountPath: /usr/share/nginx/html
       containers:
       - image: nginx:alpine
         name: nginx
         ports:
         - containerPort: 80
         resources: {}
+        volumeMounts:
+        - name: html
+          mountPath: /usr/share/nginx/html
+      volumes:
+      - name: html
+        persistentVolumeClaim:
+          claimName: guisam-pvc
 status: {}
แ… kb port-forward deployments/guisamweb 8073:80
แ… curl 127.0.0.1:8073
GuiSam was here!
แ… kb delete deploy guisamweb
แ… kb delete pvc pvc-guisam