Debian 12 bookworm
Sponsored Link

MicroK8s : Dynamic Volume Provisioning (NFS)2023/06/22

 
To use Dynamic Volume Provisioning feature when using Persistent Storage, it's possible to create PV (Persistent Volume) dynamically without creating PV manually by Cluster Administrator when created PVC (Persistent Volume Claim) by users.
[1]
Configure NFS Server on any node, refer to here.
On ths example, it uses [/home/nfsshare] directory on NFS Server that is running on [nfs.srv.world (10.0.0.35)].
[2] Install NFS Client Provisioner with Helm.
root@dlp:~#
microk8s helm3 repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
# nfs.server = (NFS server's hostname or IP address)
# nfs.path = (NFS share Path)

root@dlp:~#
microk8s helm3 install nfs-client -n kube-system --set nfs.server=10.0.0.35 --set nfs.path=/home/nfsshare nfs-subdir-external-provisioner/nfs-subdir-external-provisioner
NAME: nfs-client
LAST DEPLOYED: Thu Jun 22 00:57:10 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

root@dlp:~#
microk8s kubectl get pods -n kube-system

NAME                                                         READY   STATUS    RESTARTS       AGE
.....
.....
nfs-client-nfs-subdir-external-provisioner-5447b54dbb-nwgf9   1/1     Running   0          38s
[3] This is an example to use dynamic volume provisioning by a Pod.
root@dlp:~#
microk8s kubectl get storageclass

NAME         PROVISIONER                                                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   cluster.local/nfs-client-nfs-subdir-external-provisioner   Delete          Immediate           true                   35m

# create PVC

root@dlp:~#
vi my-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-provisioner
  annotations:
    # specify StorageClass name
    volume.beta.kubernetes.io/storage-class: nfs-client
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      # volume size
      storage: 5Gi

root@dlp:~#
microk8s kubectl apply -f my-pvc.yml

persistentvolumeclaim/my-provisioner created
root@dlp:~#
microk8s kubectl get pvc

NAME                       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS        AGE
my-provisioner             Bound    pvc-e296db93-8814-47e2-b49d-1fb33f897068   5Gi        RWO            nfs-client          5s

# PV is generated dynamically

root@dlp:~#
microk8s kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS        REASON   AGE
pvc-e296db93-8814-47e2-b49d-1fb33f897068   5Gi        RWO            Delete           Bound    default/my-provisioner              nfs-client                   35s

root@dlp:~#
vi my-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: my-mginx
spec:
  containers:
    - name: my-mginx
      image: nginx
      ports:
        - containerPort: 80
          name: web
      volumeMounts:
      - mountPath: /usr/share/nginx/html
        name: nginx-pvc
  volumes:
    - name: nginx-pvc
      persistentVolumeClaim:
        # PVC name you created
        claimName: my-provisioner

root@dlp:~#
microk8s kubectl apply -f my-pod.yml

pod/my-mginx created
root@dlp:~#
microk8s kubectl get pod my-mginx -o wide

NAME       READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
my-mginx   1/1     Running   0          18s   10.1.40.214   node01.srv.world   <none>           <none>

root@dlp:~#
microk8s kubectl exec my-mginx -- df /usr/share/nginx/html

Filesystem                                                                               1K-blocks    Used Available Use% Mounted on
10.0.0.35:/home/nfsshare/default-my-provisioner-pvc-e296db93-8814-47e2-b49d-1fb33f897068  29303808 1290752  26499072   5% /usr/share/nginx/html

# verify accessing to create test index file

root@dlp:~#
echo "Nginx Index" > index.html

root@dlp:~#
microk8s kubectl cp index.html my-mginx:/usr/share/nginx/html/index.html

root@dlp:~#
curl 10.1.40.214

Nginx Index
# when removing, to remove PVC, then PV is also removed dynamically

root@dlp:~#
microk8s kubectl delete pod my-mginx

pod "my-mginx" deleted
root@dlp:~#
microk8s kubectl delete pvc my-provisioner

persistentvolumeclaim "my-provisioner" deleted
root@dlp:~#
microk8s kubectl get pv

No resources found in default namespace.
[4] To use StatefulSet, it's possible to specify [volumeClaimTemplates].
root@dlp:~#
microk8s kubectl get storageclass

NAME                          PROVISIONER                                                RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
nfs-client                    cluster.local/nfs-client-nfs-subdir-external-provisioner   Delete          Immediate              true                   22m

root@dlp:~#
vi statefulset.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-mginx
spec:
  serviceName: my-mginx
  replicas: 1
  selector:
    matchLabels:
      app: my-mginx
  template:
    metadata:
      labels:
        app: my-mginx
    spec:
      containers:
      - name: my-mginx
        image: nginx
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      # specify StorageClass name
      storageClassName: nfs-client
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi

root@dlp:~#
microk8s kubectl apply -f statefulset.yml

statefulset.apps/my-mginx created
root@dlp:~#
microk8s kubectl get statefulset

NAME       READY   AGE
my-mginx   1/1     10s

root@dlp:~#
microk8s kubectl get pods -o wide

NAME                  READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
my-mginx-0            1/1     Running   0          14s   10.1.40.215   node01.srv.world   <none>           <none>

root@dlp:~#
microk8s kubectl get pvc

NAME                       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS        AGE
data-my-mginx-0            Bound    pvc-02a2e4cf-dafa-4295-b003-fa13f3e09568   5Gi        RWO            nfs-client          63s

root@dlp:~#
microk8s kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS        REASON   AGE
pvc-02a2e4cf-dafa-4295-b003-fa13f3e09568   5Gi        RWO            Delete           Bound    default/data-my-mginx-0             nfs-client                   96s
Matched Content