Technical Theory

Configuring Volume Types, Access Modes, and Reclaim Policies

Introduction

This tutorial will guide you through configuring different volume types, access modes, and reclaim policies in Kubernetes. Understanding these concepts is crucial for managing persistent storage for your applications effectively.

Prerequisites:

  • A running Kubernetes cluster (e.g., Minikube, Kind, or a cloud provider’s Kubernetes service).
  • kubectl configured to connect to your cluster.
  • Basic understanding of Kubernetes Pods, Services, and Deployments.

Task 1: Volume Types

Kubernetes supports various volume types, each designed for different use cases. This tutorial focuses on Persistent Volumes backed by persistent disks.

Persistent Volumes (PVs) and Persistent Volume Claims (PVCs)

Persistent Volumes (PVs) are cluster-wide resources that represent persistent storage. Persistent Volume Claims (PVCs) are requests for storage by users. Think of PVs as the actual storage and PVCs as the requests for that storage. A PVC can be bound to a PV if the PV has sufficient resources and matching access modes.

  1. Create a Persistent Volume:

    Create a file named pv.yaml with the following content:

    NODE_TYPE // yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: my-pv
    spec:
      capacity:
        storage: 1Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: standard
      hostPath:
        path: /data/my-pv
    The hostPath volume type is suitable for development and testing in single-node clusters like Minikube. In production, use appropriate volume plugins like awsElasticBlockStore, gcePersistentDisk, or azureDisk. The storageClassName should match a StorageClass.

    Apply the PV:

    NODE_TYPE // bash
    kubectl apply -f pv.yaml
    NODE_TYPE // output
    persistentvolume/my-pv created
  2. Create a Persistent Volume Claim:

    Create a file named pvc.yaml with the following content:

    NODE_TYPE // yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: standard

    Apply the PVC:

    NODE_TYPE // bash
    kubectl apply -f pvc.yaml
    NODE_TYPE // output
    persistentvolumeclaim/my-pvc created
  3. Verify the Binding:

    Check the status of the PVC to confirm it’s bound to the PV:

    NODE_TYPE // bash
    kubectl get pvc my-pvc
    NODE_TYPE // output
    NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    my-pvc    Bound    my-pv    1Gi        RWO            standard       10s

Task 2: Access Modes

Access modes define how a volume can be accessed by multiple nodes.

  • ReadWriteOnce (RWO): The volume can be mounted as read-write by a single node.
  • ReadOnlyMany (ROX): The volume can be mounted as read-only by many nodes.
  • ReadWriteMany (RWX): The volume can be mounted as read-write by many nodes.
  • ReadWriteOncePod (RWOP): The volume can be mounted as read-write by a single Pod.
  1. Understanding Access Modes with Pods:

    Create a Pod that uses the PVC:

    Create a file named pod.yaml with the following content:

    NODE_TYPE // yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      volumes:
        - name: my-volume
          persistentVolumeClaim:
            claimName: my-pvc
      containers:
        - name: my-container
          image: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: my-volume

    Apply the Pod:

    NODE_TYPE // bash
    kubectl apply -f pod.yaml
    NODE_TYPE // output
    pod/my-pod created
  2. Testing Read/Write Operations:

    Exec into the Pod:

    NODE_TYPE // bash
    kubectl exec -it my-pod -- bash

    Write a file to the mounted volume:

    NODE_TYPE // bash
    echo "<h1>Hello from Kubernetes Volume!</h1>" > /usr/share/nginx/html/index.html

    Exit the Pod shell.

  3. Verify the Content:

    Port-forward the Pod’s port 80 to your local machine:

    NODE_TYPE // bash
    kubectl port-forward my-pod 8080:80

    Open your web browser and navigate to http://localhost:8080. You should see the “Hello from Kubernetes Volume!” message.

Task 3: Reclaim Policies

Reclaim policies define what happens to the underlying volume when the PV is released.

  • Retain: The volume and its data are retained after the PV is released. You need to manually delete the volume.
  • Delete: The volume and its data are deleted automatically when the PV is released.
  • Recycle: (Deprecated) The volume is scrubbed and made available for reuse.
  1. Testing the Retain Policy:

    Delete the PVC:

    NODE_TYPE // bash
    kubectl delete pvc my-pvc
    NODE_TYPE // output
    persistentvolumeclaim "my-pvc" deleted
  2. Inspect the PV:

    Check the status of the PV:

    NODE_TYPE // bash
    kubectl get pv my-pv
    NODE_TYPE // output
    NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM             STORAGECLASS   AGE
    my-pv   1Gi        RWO            Retain           Released    default/my-pvc    standard       5m

    Notice that the PV is now in the Released state but still exists.

  3. Clean up the PV:

    Since the reclaim policy is Retain, you need to manually delete the PV:

    NODE_TYPE // bash
    kubectl delete pv my-pv
    NODE_TYPE // output
    persistentvolume "my-pv" deleted
    When using hostPath for PVs, remember to manually clean up the data in the host path directory (e.g., /data/my-pv).

Task 4: Storage Classes

Storage Classes provide a way for administrators to describe the “classes” of storage they offer. Different classes might map to different quality-of-service levels or backup policies.

  1. Create a Storage Class:

    Create a file named storage-class.yaml with the following content for a generic hostPath provisioner.

    NODE_TYPE // yaml
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: hostpath
    provisioner: kubernetes.io/no-provisioner
    reclaimPolicy: Retain
    volumeBindingMode: Immediate
    This StorageClass uses kubernetes.io/no-provisioner which means it relies on manually pre-created PVs. Dynamic provisioning with cloud provider storage classes is recommended for production environments.

    Apply the Storage Class:

    NODE_TYPE // bash
    kubectl apply -f storage-class.yaml
    NODE_TYPE // output
    storageclass.storage.k8s.io/hostpath created
  2. Create a PVC using the Storage Class:

    Modify the pvc.yaml to use the new Storage Class.

    NODE_TYPE // yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: hostpath

    Apply the PVC:

    NODE_TYPE // bash
    kubectl apply -f pvc.yaml
    NODE_TYPE // output
    persistentvolumeclaim/my-pvc created
  3. Verify the Binding:

    Check the status of the PVC to confirm it’s bound to the PV:

    NODE_TYPE // bash
    kubectl get pvc my-pvc

    You may need to manually bind it.

    NODE_TYPE // output
    NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    my-pvc    Pending   		hostpath       10s

Conclusion

In this tutorial, you learned how to configure volume types, access modes, and reclaim policies in Kubernetes. You created a Persistent Volume and a Persistent Volume Claim, explored different access modes by deploying a Pod, and tested the Retain reclaim policy. Understanding these concepts is essential for effectively managing persistent storage in Kubernetes.

Next Topic