How Kubernetes Thinks About Storage
Summary
- Kubernetes storage is a set of decoupled objects: a Pod asks for storage, and the cluster fulfills that request from real disks without the Pod knowing the details.
- Insight: The whole model exists to separate what an app needs (a 20Gi volume) from what the infrastructure provides (an AWS EBS volume in a specific zone).
- Key Concepts: A PersistentVolume (PV) is a piece of provisioned storage; a PersistentVolumeClaim (PVC) is a request for storage; a StorageClass is a template that provisions PVs on demand.
- When to Use: Any workload that must keep data across Pod restarts, rescheduling, or node failure - databases, queues, caches with persistence, and file uploads.
- Limitations/Trade-offs: Most block volumes are zone-locked and single-writer, so storage constrains scheduling as much as CPU or memory does.
- Related Topics: StorageClasses, CSI drivers, StatefulSets, volume snapshots, and access modes.
Foundations
A container's own filesystem is ephemeral. When the Pod dies, its writable layer is gone.
Kubernetes solves durable storage the same way it solves everything else: with declarative objects and a control loop that reconciles desire against reality.
The mental model has three actors that mirror how cloud infrastructure is actually consumed.
The PVC is the application developer's interface. It says "I need 20Gi of ReadWriteOnce storage of class fast-ssd" and nothing about the underlying vendor.
The PV is the cluster's representation of a real disk - an EBS volume, a GCE PD, an NFS export, or a Ceph RBD image. It carries capacity, access modes, and a reference to the driver that manages it.
The StorageClass is the factory. Instead of an admin hand-creating PVs, the StorageClass tells the cluster how to provision a fresh PV whenever a matching PVC appears.
This is the same claim-check pattern you see everywhere in Kubernetes: the consumer holds a ticket, and the platform redeems it for a real resource.
Mechanics & Interactions
Dynamic provisioning is the common path, and it is worth tracing end to end.
A developer creates a PVC that references a StorageClass by name. The PVC starts in Pending.
The external-provisioner sidecar, running alongside the CSI driver, watches for pending PVCs bound to its StorageClass.
It calls the driver's CreateVolume RPC, which asks the cloud API to carve out a real disk.
The provisioner then creates a PV object describing that disk and binds the PVC to it. The PVC moves to Bound.
Binding is exclusive and one-to-one: a bound PV serves exactly one PVC for its lifetime.
When a Pod referencing the PVC is scheduled, the kubelet and the CSI node plugin take over. ControllerPublishVolume attaches the disk to the node, then NodePublishVolume mounts it into the Pod's mount namespace.
Access modes gate concurrency. ReadWriteOnce (RWO) means one node can mount it read-write; ReadWriteOncePod narrows that to a single Pod; ReadWriteMany (RWX) allows many nodes, which only shared filesystems like NFS or EFS support.
The volumeBindingMode on the StorageClass decides when provisioning happens. WaitForFirstConsumer delays it until a Pod is scheduled, so the volume lands in the same zone as the Pod - critical for zonal block storage.
Reclaim policy governs deletion. Delete destroys the backing disk when the PVC is removed; Retain keeps it for manual recovery.
Advanced Considerations & Applications
Storage topology is the constraint that surprises teams most. A gp3 EBS volume lives in one Availability Zone, and a Pod using it can only run on nodes in that zone.
This couples the scheduler to storage. The CSI driver advertises topology labels, and the scheduler honors them so a Pod is never placed where its volume cannot attach.
For stateful clustered apps, a StatefulSet with a volumeClaimTemplates block gives each replica its own stable PVC and PV. Pod db-0 always reclaims the same volume, which is what a database replica needs.
Expansion is online for most CSI drivers: edit the PVC's requested size and the driver grows the disk and filesystem, but shrinking is never supported.
VolumeSnapshot objects provide point-in-time copies through the same CSI layer, forming the primitive that backup tooling builds on.
Performance is a per-StorageClass concern. You encode IOPS, throughput, and disk type into StorageClass parameters, then expose a small menu - fast-ssd, standard, archive - rather than letting every team hand-tune volumes.
Common Misconceptions
"A PV and a PVC are two views of the same thing." They are separate objects with separate lifecycles. The PVC is a request; the PV is the fulfillment, and one can exist without an active binding.
"ReadWriteMany just needs the right access mode set." The access mode is only honored if the underlying driver actually supports shared access. Setting RWX on an EBS-backed class does not make block storage multi-writer.
"Deleting a Pod deletes its data." Deleting a Pod releases the volume but leaves the PVC and PV intact. Data survives until the PVC itself is deleted under a Delete reclaim policy.
"StorageClasses are optional detail." The default StorageClass silently backs any PVC that omits one, so an unreviewed default can put production data on the wrong disk tier.
"Any volume can move to another zone." Zonal block volumes cannot cross AZ boundaries; migration means snapshot, restore, and reattach.
FAQs
What is the difference between a volume and a PersistentVolume? A volume is a Pod-scoped mount that shares the Pod's lifecycle. A PersistentVolume is a cluster resource that outlives any single Pod.
Do I ever create PVs by hand? Rarely. Static provisioning is used for pre-existing NFS exports or imported disks; dynamic provisioning via StorageClasses covers most cases.
Why is my PVC stuck in Pending? Usually no StorageClass matched, no provisioner is running, or WaitForFirstConsumer is waiting for a schedulable Pod.
Can two Pods share one PVC? Only if the PV's driver supports ReadWriteMany, or both Pods land on the same node with a ReadWriteOnce volume.
What happens to the disk when I delete the PVC? With reclaim policy Delete the backing disk is destroyed; with Retain it is kept for manual reuse.
Is Docker involved in mounting these volumes? No. On nodes, containerd via the CRI plus the CSI plugin handle attach and mount; Docker is a build and local-dev tool here.
Related
- K8s Storage Basics
- CSI Drivers
- Stateful Data on Kubernetes
- Backup PVs
- Storage Architecture Best Practices
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).