The Manual Problem
In the early days of Kubernetes, administrators had to manually pre-create a pool of PVs — guessing ahead of time what sizes developers would need. If a developer needed 37Gi and the smallest available PV was 50Gi, they'd get the 50Gi PV and waste 13Gi. If no PV matched, the PVC would sit in Pending forever. This static provisioning model was operationally painful at scale.
Dynamic Provisioning with StorageClasses
StorageClasses solve this by enabling dynamic provisioning. A StorageClass is a template that tells Kubernetes how to create new storage on demand — which provisioner to call, and with what parameters. When a PVC references a StorageClass, Kubernetes automatically creates a matching PV by calling the storage provider's API.
A StorageClass names the provisioner (the CSI driver that actually talks to the storage backend), backend-specific parameters (volume type, IOPS, filesystem), a reclaim policy, a volume binding mode, and whether PVCs against it can be resized later. The volumeBindingMode: WaitForFirstConsumer setting is particularly important in multi-zone clusters. Without it, a volume might be provisioned in us-east-1a while the Pod that needs it gets scheduled in us-east-1b — and EBS volumes can't cross availability zones. WaitForFirstConsumer delays provisioning until Kubernetes knows which node (and therefore which AZ) the Pod will run on.
The Default StorageClass
Most clusters have a default StorageClass. If a PVC doesn't specify a storageClassName, Kubernetes automatically assigns the default. You can check which StorageClass is default with kubectl get sc — it will be marked with (default) in the output.