Skip to content

How to Use Persistent Volumes and Claims in Kubernetes

DodaTech 2 min read

In this tutorial, you'll learn about How to Use Persistent Volumes and Claims in Kubernetes. We cover key concepts, practical examples, and best practices.

The Problem

When a pod restarts or is rescheduled to another node, all data written to its local filesystem is lost. Containers are ephemeral by design. Persistent Volumes (PV) and Persistent Volume Claims (PVC) provide storage that survives pod restarts and rescheduling. PVs are storage resources in the cluster, while PVCs are requests for storage by a user or pod. Without them, stateful applications like databases and file stores cannot run reliably in Kubernetes because they lose all data whenever a pod moves or restarts.

Quick Fix

1. Create a PersistentVolume (static provisioning)

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

Apply with kubectl apply -f pv.yaml. hostPath is for development; use cloud volumes (EBS, GCE PD, Azure Disk) in production.

2. Create a PersistentVolumeClaim

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

Apply with kubectl apply -f pvc.yaml. Kubernetes binds this to a matching PV. The PVC must be in the same namespace as the pod using it.

3. Use the PVC in a pod

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

4. Check PV and PVC status

kubectl get pv
kubectl get pvc

Expected output:

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

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

5. Use a StorageClass for dynamic provisioning

Create a PVC without a pre-existing PV:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard

The cluster provisioner creates the PV automatically.

6. Access modes explained

Mode Description
ReadWriteOnce (RWO) Single node read-write
ReadOnlyMany (ROX) Many nodes read-only
ReadWriteMany (RWX) Many nodes read-write

7. Expand a PVC (if StorageClass supports it)

kubectl edit pvc my-pvc
# Change storage: 5Gi to storage: 10Gi

Use kubectl describe for Detailed Diagnostics

kubectl describe pod <pod-name>
# Events:
#   Type     Reason     Age   From     Message
#   ----     ------     ----  ----     -------
#   Warning  BackOff    5m    kubelet  Back-off restarting failed container

The Events section at the bottom of kubectl describe output is the most valuable diagnostic tool. It shows a chronological log of scheduling failures, image pull errors, and container crashes.

Prevention

  • Use storageClassName in PVCs for dynamic provisioning in cloud environments
  • Choose the right accessModes based on your workload: RWO for databases, RWX for shared files
  • Set reclaim policies (Retain, Recycle, Delete) based on data retention requirements
  • Use Retain for production data that must not be deleted when the PVC is removed

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro