Kubernetes Dynamic Storage Provisioning with StatefulSets

PracticiumMay 10, 2026

The Mechanics of Persistent Volumes in Kubernetes

One of the most common questions in Kubernetes storage management is how space is utilized between PersistentVolumes (PV) and PersistentVolumeClaims (PVC). By default, Kubernetes maintains a strict 1:1 binding. If you create a 10GB PV and a PVC claims only 4GB, the remaining 6GB remains locked and unavailable to other claims, as the PV is marked as 'Bound'.

PV and PVC Binding in Kubernetes
PV and PVC Binding in Kubernetes

The 1:1 Binding Limitation

Because of the strict 1:1 mapping, pre-provisioning multiple PVs for a single Deployment doesn't work as expected. A Deployment uses a single PVC name for all its replicas. Since that one PVC can only bind to one PV, all your pods will attempt to mount the exact same volume, leading to 'Multi-Attach' errors or data corruption if the storage is not designed for shared access.

Scaling Storage with StatefulSets

When scaling applications that require unique storage for each instance, such as databases, standard Deployments fall short because they share the same PVC. StatefulSets solve this through volumeClaimTemplates, which automate the provisioning of unique disks for every new replica.

Why Deployments Cannot Pre-Provision for Scaling

ConstraintDeployment BehaviorImpact
Hardcoded PVCAll replicas use the exact same PVC name.They all compete for the same single PV.
1:1 MappingPVC binds to exactly one PV.You cannot 'pre-create' 5 PVs and hope 5 replicas find them.
Node LockingRWO volumes lock to a single worker node.Replica 2 on Node B cannot mount the PV held by Node A.

Dynamic Provisioning Workflow

ComponentRole in Provisioning
StorageClassThe blueprint that defines which storage driver (AWS EBS, GPD, etc.) to use.
volumeClaimTemplatesThe template within a StatefulSet that triggers a new PVC for every replica.
PVCThe specific request generated for each pod (e.g., data-web-app-0, data-web-app-1).
CSI DriverThe interface that communicates with the Cloud Provider to create the physical disk.

Implementation: StatefulSet YAML Example

To enable dynamic provisioning such that scaling up automatically creates new storage, use the following configuration structure:

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-app
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "fast-provisioning"
resources:
requests:
storage: 2Gi

What Happens During Scaling?

When you run a command like kubectl scale statefulset web-app --replicas=3, Kubernetes triggers a specific sequence to ensure storage integrity:

  • Pod Creation: Kubernetes identifies that 'web-app-2' (the third pod) needs to be created.
  • PVC Generation: Before the pod starts, Kubernetes generates a unique PVC named 'www-web-app-2' based on your template.
  • Automatic Provisioning: The StorageClass notices the new PVC, contacts the cloud API, and creates a new physical 2GB disk.
  • PV Creation: A PersistentVolume (PV) is automatically created and bound to that specific PVC.
  • Pod Startup: Only after the storage is ready will 'web-app-2' start and mount its own unique 2GB volume.

Key Benefits of StatefulSet Provisioning

BenefitDescription
Unique IdentityIf a pod dies and restarts, Kubernetes ensures it reconnects to its specific volume.
No Manual WorkEliminates the need to pre-create hundreds of PVs manually for large clusters.
Decoupled LifecyclePVCs remain intact after pod deletion, preventing accidental data loss.

Deployment vs. StatefulSet Scaling

FeatureDeployment + PVCStatefulSet + Template
Storage MappingAll replicas share 1 PVCEach replica gets 1 unique PVC
Scaling BehaviorPods compete for same disk spaceNew PV is provisioned for every new pod
Access ModeOften requires ReadWriteManyWorks perfectly with ReadWriteOnce
Best Use CaseStateless Apps / Shared ConfigDatabases / Distributed Systems

Key Takeaways

  • Kubernetes PV-PVC binding is 1:1; you cannot 'slice' a single PV into multiple PVCs.
  • Pre-provisioning fails for Deployments because they lack unique pod identities to link to unique PVs.
  • Dynamic Provisioning via StorageClasses eliminates the need to manually pre-create PVs.
  • StatefulSets are mandatory when scaling workloads that require independent data persistence for each pod instance.