PersistentVolumeClaims
A PersistentVolumeClaim is how a Pod asks for and mounts persistent storage.
Syntax
volumes:
- name: <name>
persistentVolumeClaim:
claimName: <pvc-name>Pods never reference a PersistentVolume directly. They reference a PersistentVolumeClaim (PVC) — a request that Kubernetes fulfills with a matching PV.
The workflow
- You create a PVC stating how much storage and which access mode you need.
- Kubernetes finds a PV that satisfies it (or provisions one dynamically).
- The PVC's status becomes
Bound. - Your Pod mounts the PVC by name and reads/writes files normally.
Why the indirection?
It decouples what the app needs from how storage is provided. The same manifest works whether the backing disk is an AWS EBS volume, a GCE disk, or an on-prem NFS share.
Example
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Pod
metadata:
name: db
spec:
containers:
- name: postgres
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: data-claimWhen to use it
- A developer creates a PersistentVolumeClaim for 5 Gi of storage and the cluster dynamically provisions the underlying disk without needing ops involvement.
- A StatefulSet declares a volumeClaimTemplate so each pod replica automatically gets its own dedicated PVC and does not share state with other replicas.
- An SRE resizes a PVC from 10 Gi to 20 Gi using kubectl patch after the storage class supports volume expansion, without downtime.
More examples
PersistentVolumeClaim manifest
Requests 5 Gi of ReadWriteOnce storage from the standard storage class, triggering dynamic provisioning.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5GiMount PVC in a pod
Mounts the app-data PVC into the postgres container at its data directory, persisting DB data across pod restarts.
spec:
containers:
- name: db
image: postgres:15
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: app-dataExpand a PVC online
Patches the PVC storage request to 20 Gi; if the StorageClass supports expansion, the volume grows without pod restart.
kubectl patch pvc app-data -p \
'{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
kubectl get pvc app-data
# CAPACITY: 20Gi STATUS: Bound
Discussion