Module 7: Kubernetes Storage – Volumes & Persistent Volumes

DevOpsLaunchpadDevOpsLaunchpad
4 min read

We worked with Deployments, Services, ConfigMaps, and Secrets. But what happens when your pods need to store and persist data?

By default, when a pod is deleted or restarted, all data inside it is lost. That’s fine for stateless applications (like a simple frontend), but not acceptable for stateful apps (like databases).

That’s where Kubernetes Storage comes into play.


🔑 Why Storage Matters in Kubernetes

  • Pods are ephemeral → when they die, their filesystem goes too.

  • Databases & stateful workloads require data to survive restarts.

  • Kubernetes provides multiple ways to attach storage volumes to pods.


📂 Understanding Kubernetes Volumes

A Volume is a directory accessible to containers in a pod. Unlike container filesystems, volumes outlive the container’s lifecycle (but not always the pod’s).

Common Volume Types

  1. emptyDir

    • Created when a pod starts, deleted when the pod stops.

    • Useful for temporary storage (e.g., scratch space).

  2. hostPath

    • Mounts a directory from the node’s filesystem into a pod.

    • Useful for accessing node-local files, but not portable.

  3. configMap / secret volumes

    • Mounts a ConfigMap or Secret into the container as a file.

    • Great for injecting configuration or credentials.


🗂 Persistent Volumes (PV) and Persistent Volume Claims (PVC)

While volumes like emptyDir are tied to the pod lifecycle, Persistent Volumes allow data persistence even if the pod is deleted.

Persistent Volume (PV)

  • A cluster-wide storage resource.

  • Created by an administrator (e.g., backed by NFS, EBS, GCE disk).

  • Managed independently from pods.

Persistent Volume Claim (PVC)

  • A request for storage by a pod.

  • Users don’t care about the underlying storage; they just request size, access mode, etc.

  • PVC binds to a matching PV.


⚙️ Storage Classes & Dynamic Provisioning

  • Without StorageClasses, admins must manually create PVs.

  • StorageClass automates PV creation using a provisioner (e.g., AWS EBS, GCP Persistent Disk, Ceph, etc.).

  • Dynamic provisioning = PVC automatically gets a new PV.


🖥 Example: PV + PVC + Pod

1️⃣ Create a Persistent Volume (PV)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

2️⃣ Create a Persistent Volume Claim (PVC)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi

Once you create the PV and PVC YAMLs, you can manage them with CLI commands:

List all Persistent Volumes

kubectl get pv

Output example:

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM           STORAGECLASS   AGE
my-pv    1Gi        RWO            Retain           Bound    default/my-pvc  standard       5m

List all Persistent Volume Claims

kubectl get pvc

Output example:

NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc    Bound    my-pv    1Gi        RWO            standard       5m

Describe a Persistent Volume

kubectl describe pv my-pv

You’ll see:

  • Capacity (how much storage)

  • Access Modes (RWO, ROX, RWX)

  • Reclaim Policy (Retain, Delete, Recycle)

  • Status (Available/Bound/Released/Failed)

  • Which PVC it’s bound to

Describe a Persistent Volume Claim

kubectl describe pvc my-pvc

You’ll see:

  • Requested storage size

  • Bound PV name

  • Access Modes

  • Events (helpful for troubleshooting)


⚙️ Access Modes Explained

  • ReadWriteOnce (RWO) → only one node can mount the volume for read/write.

  • ReadOnlyMany (ROX) → multiple nodes can read the volume.

  • ReadWriteMany (RWX) → multiple nodes can read/write at the same time.


🧹 Reclaim Policies

When a PVC is deleted, the PV follows a reclaim policy:

  • Retain → data is preserved, admin must manually clean up.

  • Delete → data and volume are deleted automatically.

  • Recycle (deprecated) → basic scrub and make PV available again.


3️⃣ Attach PVC to a Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: storage
  volumes:
  - name: storage
    persistentVolumeClaim:
      claimName: my-pvc

✅ Here, the pod uses the PVC, which in turn binds to the PV, ensuring persistent storage.

🚀 Hands-On Demo Ideas

  • Create PV + PVC + Pod, then run:

      kubectl exec -it my-pod -- sh
      echo "Hello from PV" > /usr/share/nginx/html/index.html
    

    Delete and recreate the pod → check the file is still there.

  • Run kubectl get pv,pvc to watch the binding.

  • Try changing reclaim policy and see what happens when you delete the PVC.


🏁 Conclusion

Kubernetes storage bridges the gap between stateless containers and stateful applications. With Volumes, Persistent Volumes, PVCs, and StorageClasses, Kubernetes allows workloads to store and persist data reliably.

0
Subscribe to my newsletter

Read articles from DevOpsLaunchpad directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

DevOpsLaunchpad
DevOpsLaunchpad