Topic 2.3
Volumes, PersistentVolumes & PersistentVolumeClaims
In one line
A pod's own filesystem disappears the moment it's replaced — a Volume gives it storage that outlives the container, and a PersistentVolume/Claim pair is how that storage survives the pod itself being deleted and recreated.
Think of it like this
Writing notes on a whiteboard in a hotel room you'll never see again versus writing them in a notebook you carry with you — anything written directly to a pod's own container filesystem is the whiteboard: gone the instant that specific pod is replaced (Phase 0.3's disposability, revisited here with real consequences).
Key ideas
- 01
A basic VOLUME is storage attached to a pod that outlives any single CONTAINER RESTART within that pod (useful for sharing files between containers in the same pod, or surviving a container crash-and-restart) — but it does NOT outlive the POD itself being deleted and recreated, which happens routinely during normal Kubernetes operation.
- 02
A PERSISTENTVOLUME (PV) represents an actual piece of real storage (a cloud disk, a network filesystem) provisioned in the cluster, independent of any specific pod's lifecycle entirely. A PERSISTENTVOLUMECLAIM (PVC) is a pod's REQUEST for storage matching certain criteria (size, access mode) — Kubernetes matches (BINDS) a PVC to a suitable available PV, and the pod then mounts that PVC.
- 03
This two-layer design (PV provisioned separately, PVC requested by a pod) deliberately separates 'what storage actually exists' from 'what a specific application needs' — an application's manifest only ever needs to reference a PVC by name; it doesn't need to know or care about the specific underlying disk, cloud provider, or storage technology backing it.
- 04
Crucially, a PVC (and its bound PV) SURVIVES a pod being deleted and recreated — this is exactly what makes real persistent state possible in Kubernetes: a database pod using a PVC can be deleted, rescheduled onto an entirely different node, and come back up still mounting the SAME data it had before, which a plain volume alone could never provide.
- 05
accessModeson a PVC control how it can be mounted:ReadWriteOnce(mountable by one node at a time — the common case for most databases),ReadOnlyMany(many nodes can mount it, read-only), andReadWriteMany(many nodes can mount it for both reading and writing — requires a storage backend that genuinely supports this, not all do).
Code & diagrams
A plain volume dies with the pod; a PVC-backed PersistentVolume survives it.
A PVC requesting storage, and a pod mounting it — the storage outlives this specific pod.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-data-pvc
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-storage
spec:
containers:
- name: my-app
image: my-registry/my-app:1.5.0
volumeMounts:
- name: data
mountPath: /app/data
volumes:
- name: data
persistentVolumeClaim:
claimName: my-data-pvc # references the PVC by name — doesn't know or care about the real disk underneathProve the data survives the pod being deleted entirely.
kubectl apply -f pvc-and-pod.yaml
kubectl get pvc my-data-pvc
# STATUS: Bound — the PVC found and attached to a matching PersistentVolume
# Write something into the persistent volume
kubectl exec my-app-with-storage -- sh -c "echo 'important data' > /app/data/file.txt"
# Delete the POD entirely — NOT the PVC
kubectl delete pod my-app-with-storage
kubectl apply -f pvc-and-pod.yaml # recreate the pod
# The data is still there — it lived in the PV, not the pod
kubectl exec my-app-with-storage -- cat /app/data/file.txt
# important dataExplain it without notes
Why does a PersistentVolumeClaim exist as a separate object from the PersistentVolume itself, rather than a pod just directly requesting a specific disk?
You write data to a plain volume (not a PVC-backed one) inside a pod, then that pod gets deleted and recreated. What happens to that data?
Practice
Create the example PVC and pod, write a file into the mounted storage, delete the pod, recreate it, and confirm the file is still there.
Check kubectl get pvc and identify the STATUS column — confirm it shows Bound, and look up (via kubectl get pv) which actual PersistentVolume it's bound to.
Trade-offs
- ↔
PVC-backed storage is essential for genuinely persistent workloads, but it adds real complexity and cost compared to a stateless pod with no storage needs at all — for anything that's genuinely fine losing its local data on every restart (a cache that can be fully rebuilt, temporary scratch space), a plain volume (or no volume at all) is simpler and avoids unnecessary provisioned storage sitting around.
Done when you can
I understand why a plain volume doesn't survive a pod being deleted and recreated, but a PVC-backed one does.
I can create a PVC, mount it in a pod, and confirm data survives across pod recreation.
I understand why PVC and PersistentVolume are kept as separate objects.