Kubernetes Storage
Storage Classes and Dynamic Provisioning
Automating volume creation with CSI drivers.
Interview: Focus on dynamic volume provisioning vs static provisioning. Explain the role of the Container Storage Interface (CSI) driver. Be prepared to explain why volumeBindingMode: WaitForFirstConsumer is crucial in multi-AZ cloud environments to prevent scheduling deadlocks.
Introduction
Static volume provisioning requires cluster administrators to manually create physical disks and write matching Kubernetes PersistentVolume objects before developers can submit claims. This model does not scale in modern cloud-native infrastructures.
To automate this process, Kubernetes implements Dynamic Volume Provisioning. By defining a StorageClass (SC), administrators describe the "classes" of storage they offer (e.g., fast SSD, cheap HDD, multi-AZ replicated storage). When a developer creates a PVC referencing a StorageClass, Kubernetes automatically provisions the physical disk in the cloud and registers the PV.
Why It Matters
Dynamic provisioning removes manual ticket operations. Developers get instant storage access, and cloud costs are minimized since volumes are created on-demand and deleted automatically when applications are torn down.
Real-World Analogy
Static provisioning is like a restaurant that pre-cooks 50 burgers (PVs) in the morning and leaves them on the counter. If a customer (PVC) wants a vegan burger, they must wait for the chef to manually prepare one. Dynamic provisioning is like a vending machine (StorageClass). The user inputs a token (PVC), selects a drink, and the machine instantly dispenses a freshly prepared drink (dynamic PV) of the exact requested type and size.
How It Works: The CSI Abstraction
Dynamic provisioning is powered by the Container Storage Interface (CSI). CSI is an industry-standard open specification that allows storage vendors (like AWS, NetApp, Portworx, or Ceph) to write storage plugins that work seamlessly in Kubernetes without modifying core Kubernetes code:
- Developer submits a PVC specifying a
storageClassName: gp3. - The Kubernetes volume controller detects the claim and looks up the corresponding
StorageClassresource. - The controller invokes the external CSI driver provisioner specified in the StorageClass (e.g.,
ebs.csi.aws.com). - The CSI driver makes an API call to the cloud infrastructure provider (e.g. AWS EC2 CreateVolume) to allocate a physical disk of the requested size.
- The CSI driver creates a matching
PersistentVolumeobject in Kubernetes and binds it 1:1 to the PVC. - The Pod mounts the volume, and the kubelet instructs the host kernel to format the new disk and mount the path.
Internal Architecture: Volume Binding Modes
One of the most critical fields in a StorageClass is volumeBindingMode. It controls exactly *when* the PV is provisioned and bound:
- Immediate: The volume controller provisions the PV instantly when the PVC is created. This works for regional or single-AZ clusters. However, in multi-AZ clusters, this causes deadlocks: a volume might be provisioned in availability zone
us-east-1a, but the Pod gets scheduled inus-east-1b. Cloud block stores cannot cross AZ boundaries, rendering the volume unmountable. - WaitForFirstConsumer: Delay provisioning until a Pod requesting the PVC is created. The Kubernetes scheduler runs first, selecting a node that matches all scheduling rules (resource limits, taints, affinities, and availability zones). Once the node is selected, the CSI driver provisions the volume in the *exact same availability zone* as that node, resolving topology conflicts.
Practical Example
Here are the manifests for an AWS EBS gp3 StorageClass implementing WaitForFirstConsumer and a PVC requesting storage from it:
Common Mistakes
- Using Immediate binding in Multi-AZ clusters: This is the default in many older manifests. It leads to Pods stuck in
VolumeNodeAffinityConflictbecause the scheduler cannot place the Pod on the node where the volume was pre-provisioned. - Missing CSI driver installation: Deploying a StorageClass (e.g.
ebs.csi.aws.com) without installing the matching driver on the worker nodes. The PVCs will stay inPendingstatus forever with events statingprovisioner "ebs.csi.aws.com" not found.
Quick Quiz
Q1: Why is "WaitForFirstConsumer" preferred over "Immediate" volume binding in AWS/GCP clusters?
A) It makes disk provisioning faster.
B) It delays disk creation until the scheduler determines which AZ the Pod must run in, avoiding AZ mounting mismatches.
C) It bypasses the CSI driver entirely.
Answer: B — Delaying volume creation ensures the disk is provisioned in the availability zone matching the scheduled node.
Scenario-Based Challenge
Production Scenario:
Your company runs a database workload whose storage size needs to scale over time. The disk starts at 100Gi but may need to grow to 500Gi. How can you configure Kubernetes to support this without killing the database container?
View Solution
To support volume expansion, you must set allowVolumeExpansion: true inside the StorageClass resource. Once enabled, you can expand the volume by editing the PVC manifest (e.g. via kubectl edit pvc app-db-claim) and increasing the spec.resources.requests.storage value to 500Gi. The CSI driver will instruct the cloud API to expand the physical disk, and the filesystem will resize automatically (often online while the Pod remains running). Note that you cannot decrease volume size.
Debugging Exercise
Stuck PVC:
A developer runs kubectl get pvc and sees db-claim stuck in Pending. When running kubectl describe pvc db-claim, they see the warning: FailedToProvision: Failed to create volume: WebIdentityErr: failed to retrieve credentials.
Root Cause: The cloud provider CSI driver (e.g., AWS EBS CSI driver) does not have IAM permissions to invoke the cloud storage APIs (like EC2 CreateVolume). The controller pod needs service account annotations mapping to an IAM Role with appropriate policies.
Fix: Setup IAM Roles for Service Accounts (IRSA). Create an IAM policy allowing EBS management, bind it to an IAM role, and annotate the ebs-csi-controller-sa service account in the kube-system namespace with the role's ARN. Restart the CSI daemonset.
Interview Questions
1. What is the role of a CSI driver inside a Kubernetes cluster?
The CSI (Container Storage Interface) driver acts as a translator between the Kubernetes API and the storage vendor's API. It registers custom controllers that intercept volume attach/detach/mount commands from Kubernetes and execute them against the physical storage backend (e.g. creating block disks, locking attachments, mapping network paths).
2. Can you decrease the size of a PersistentVolumeClaim after expanding it?
No. Shrinking volumes is not supported by Kubernetes or the majority of cloud storage providers because decreasing a filesystem's boundary runs a high risk of data corruption. You can only expand volumes.
Production Considerations
In production clusters, define default StorageClasses with explicit encryption flags enabled (encrypted: "true"). Always utilize WaitForFirstConsumer to avoid scheduling deadlocks in multi-zone regions. Set up alerts for disk expansion limits, as major cloud providers limit how frequently you can resize an individual volume (e.g., AWS EBS throttling allows resizing only once every 6 hours).