Every container gets a writable layer on top of its image. Writes go there. When the container is removed, the layer is removed.
Pod db-0
container postgres
image layers (read-only)
writable layer (deleted with the container)A Deployment replacing a Pod, a node reboot, a crash loop: each one discards the layer. A database in a bare container loses its data on the first restart.
Volumes
A volume is a directory mounted into a container from outside the writable layer. The source decides how long the data lives:
emptyDir lives as long as the Pod. Deleted with the Pod.
hostPath a path on the node. Survives the Pod, tied to that node.
PVC a claim on cluster storage. Survives the Pod and the node.The claim model
Three objects separate "I need 1 GB" from "here is a disk":
Pod ──mounts──▶ PersistentVolumeClaim ──bound to──▶ PersistentVolume ──backed by──▶ disk
(namespaced, 1Gi RWO) (cluster-scoped, 2Gi RWO)- PersistentVolume (PV): a piece of storage in the cluster. Cluster-scoped. Has a capacity, access modes, a reclaim policy and a backing (hostPath, local disk, cloud volume).
- PersistentVolumeClaim (PVC): a request for storage in a namespace. Has a size and access modes. Binds to one PV.
- StorageClass: a recipe for creating PVs on demand. Names a provisioner, a reclaim policy and a binding mode.
The Pod names the claim. The claim is bound to a volume. The Pod never names the volume.
Access modes
ReadWriteOnce (RWO) one node can mount it read-write
ReadOnlyMany (ROX) many nodes can mount it read-only
ReadWriteMany (RWX) many nodes can mount it read-writeA claim binds only to a volume that offers every mode the claim asks for.
Reclaim policies
What happens to a PV when its claim is deleted:
Delete the PV and the data are removed
Retain the PV stays, phase Released, data intact, claimRef still setStatic vs dynamic
Static: an administrator creates PVs by hand. A PVC with storageClassName: "" binds to the first Available PV that fits.
Dynamic: a PVC names a StorageClass (or gets the default). The class's provisioner creates a PV sized to the claim.
This cluster has one class:
kubectl get storageclasslocal-path is the default. Its binding mode is WaitForFirstConsumer: a claim on it stays Pending until a Pod mounts it, then a PV is created and bound.