StorageClass & PVC
A StorageClass defines how volumes are provisioned; a PersistentVolumeClaim requests one for a pod.
Syntax
kubectl get storageclassKubernetes separates what storage you want from how it's created. Two objects make this work:
- StorageClass — a template that says which provisioner to use and with what settings (for EBS: volume type, IOPS, encryption).
- PersistentVolumeClaim (PVC) — a pod's request for a volume of a given size and class. The CSI driver dynamically creates the real volume to satisfy it.
Dynamic provisioning flow
- You define a StorageClass once.
- A pod references a PVC.
- The driver provisions a matching EBS/EFS volume and binds it.
Set a default StorageClass so PVCs without an explicit class still get storage.
Example
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
encrypted: "true"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: gp3
resources:
requests:
storage: 20GiWhen to use it
- A platform team sets a default StorageClass so developers can create PVCs without specifying a storage backend, and all volumes use gp3 EBS automatically.
- A stateful application team uses WaitForFirstConsumer binding mode to ensure EBS volumes are always created in the same Availability Zone as the pod.
- A data team uses StorageClass parameters to provision high-IOPS io2 volumes for database pods while sharing a single cluster with teams using cheaper gp3.
More examples
Mark a StorageClass as default
Sets the ebs-gp3 StorageClass as the cluster default so PVCs without a storageClassName annotation are automatically fulfilled by it.
kubectl patch storageclass ebs-gp3 \
-p '{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class": "true"}}}'StatefulSet with volumeClaimTemplates
A StatefulSet with a volumeClaimTemplate that auto-provisions a dedicated 20 GiB EBS PVC per replica using the ebs-gp3 StorageClass.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: ebs-gp3
resources:
requests:
storage: 20GiInspect PVC and bound PV
Shows the PVC binding status and the underlying PersistentVolume created by the CSI driver, confirming the StorageClass provisioned the volume correctly.
kubectl get pvc postgres-data
kubectl describe pvc postgres-data
kubectl get pv $(kubectl get pvc postgres-data -o jsonpath='{.spec.volumeName}')
Discussion