Kubernetes Curriculum
On this page
- Storage Class Parameters
- The Storage Provisioning Problem Kubernetes Solved
- The DevOps Dream: Dynamic Provisioning
- The StorageClass as a Contract
- The Provisioner: Who Creates the Volume?
- Understanding Provisioner Selection
- How Provisioner Discovery Works
- Parameters: Cloud-Specific Configuration
- AWS EBS Parameters
- Google Cloud Parameters
- Dynamic Provisioning Workflow: From PVC to Running Pod
- Complete Step-by-Step Flow
- Why StorageClass Parameters Matter for Performance
- Database Workload
- Cache/Session Store Workload
- Backup/Archive Workload
- Shared File System (logs, uploads)
- Failure Modes and Troubleshooting
- Failure 1: Provisioner Not Found
- Failure 2: Parameters Invalid
- Summary: StorageClass as Infrastructure Code
Storage Class Parameters
The Storage Provisioning Problem Kubernetes Solved
Before Kubernetes, deploying stateful applications was tedious:
Old Process (Manual):
- DevOps admin logs into AWS console
- Creates an EBS volume (say, 100GB)
- Creates Kubernetes PersistentVolume yaml pointing to vol-xyz123
- Developer creates PersistentVolumeClaim requesting 100GB
- Waits for manual matching
- If volume too small: repeat process, new volume, new PV yaml
- If volume too large: wasted money, can't shrink
This was static provisioning—each volume required manual AWS work plus Kubernetes YAML.
The DevOps Dream: Dynamic Provisioning
New Process (Kubernetes):
- Developer writes: "I need 100GB storage with gp3 performance"
- Creates PVC
- Kubernetes automatically creates the volume
- Volume mounts
- Done
This is dynamic provisioning—Kubernetes automates the entire workflow.
What is a StorageClass?
A StorageClass is a template definition that tells Kubernetes:
"When someone creates a PVC requesting storage of type X, here's how to automatically provision it"
It answers several critical questions:
- Who provisions? (Which CSI driver?)
- Where? (Which cloud region, subnet, AZ?)
- What kind? (Performance tier, encryption, type?)
- How much control? (Can it be deleted? Resized?)
- When to bind? (Before or after pod scheduling?)
The StorageClass as a Contract
Think of a StorageClass like a service level agreement (SLA):
When a developer creates a PVC with storageClassName: database-tier, they're saying: "Give me what this contract defines."
The Provisioner: Who Creates the Volume?
The provisioner field specifies which CSI driver handles volume creation.
Understanding Provisioner Selection
Different provisioners exist because storage systems are fundamentally different:
Block Storage Provisioners:
ebs.csi.aws.com— AWS Elastic Block Store (single AZ, single-node attach)disk.csi.azure.com— Azure Managed Diskpd.csi.storage.gke.io— Google Persistent Disk
File System Provisioners:
efs.csi.aws.com— AWS Elastic File System (multi-AZ, multi-node, NFS)smb.csi.k8s.io— SMB volumes (Windows fileshare style)
Distributed Storage Provisioners:
ceph.rook.io— Ceph (open-source distributed storage)netapp.trident.io— NetApp Trident (enterprise SAN)
Local/Test Provisioners:
kubernetes.io/no-provisioner— Local volumes (no dynamic provisioning)
How Provisioner Discovery Works
When a PVC is created, Kubernetes:
- Reads the
storageClassName - Finds the StorageClass definition
- Looks up the
provisionerfield - Finds the CSI driver pod(s)
- Sends: "Create a volume with these parameters"
- CSI driver calls the cloud API
- Volume is created and returned
Parameters: Cloud-Specific Configuration
The parameters section is highly specific to each provisioner. Different clouds have different options.
AWS EBS Parameters
Understanding these parameters:
type: Selects the EBS volume class
gp2: General Purpose v2 (2013, older, coupled IOPS-to-size)gp3: General Purpose v3 (2020, modern, independent IOPS/throughput)io1/io2: High IOPS provisioned volumes (expensive)st1: Throughput-optimized (for big data sequential access)sc1: Cold/archive storage (cheapest, slowest)
Why gp3 is Now Default:
- gp2 couples IOPS to capacity (3 IOPS per GB)
- If you need 9000 IOPS, you must buy 3000GB minimum
- gp3 decouples them (buy 100GB + 9000 IOPS independently)
- gp3 is cheaper, more flexible, better performance
iops: Guarantees specific I/O throughput
iops: "3000"guarantees 3000 operations per second minimum- AWS will deliver this consistently (with tail latency bounds)
- Important for databases, transaction processing
throughput: Bandwidth guarantee (gp3 only)
throughput: "125"guarantees 125 MB/s- Separate from IOPS (you can have low IOPS, high throughput or vice versa)
- Important for sequential workloads (big data, backups)
encrypted: Always enable for sensitive data
- Encryption at rest (data encrypted when written to disk)
- AWS handles key management (unless you use custom kmsKeyId)
- Compliance requirement for HIPAA, PCI-DSS, SOC2
Google Cloud Parameters
Different clouds have different concepts:
- Google uses "persistent disk" instead of "EBS"
- Google supports regional replication natively
- Parameter names and meanings vary by provider
Dynamic Provisioning Workflow: From PVC to Running Pod
Understanding this workflow is critical for troubleshooting.
Complete Step-by-Step Flow
Step 1: Developer Creates PVC
Developer thinks in terms of: "I need 100GB of fast storage."
Step 2: Kubernetes Validates Storage Class
The PVC controller validates:
- Does StorageClass "database-tier" exist?
- Is the provisioner installed and running?
- Does the StorageClass allow this PVC's access mode?
If any check fails, PVC stays Pending forever.
Step 3: CSI Provisioner Watches and Acts
The provisioner sidecar container (running in the CSI driver pod) watches for unprovisioned PVCs:
Step 4: CSI Driver Calls Cloud API
The driver calls AWS:
AWS processes the request asynchronously:
- Allocates storage in specified AZ
- Configures IOPS and throughput
- Returns:
Volume ID: vol-0123456789abcdef0
Step 5: Kubernetes Creates PersistentVolume
The provisioner creates a PV object:
Step 6: PVC Binds to PV
The bind controller matches:
- PVC requesting 100Gi ↔ PV offering 100Gi
- Access modes match
- StorageClass match
PVC status changes: Pending → Bound
Step 7: Pod References the PVC
A pod spec can now use the PVC:
Step 8: kubelet Attaches Volume to Node
When the pod is scheduled to a node:
- kubelet sees the volume is needed
- Calls the node plugin (CSI DaemonSet)
- Node plugin tells AWS: "Attach vol-0123456789abcdef0 to instance i-abc123"
- AWS attaches the volume
- Device appears in the OS (e.g.,
/dev/nvme1n1)
Step 9: Node Plugin Formats and Mounts
The node plugin:
- Formats the raw device:
mkfs.ext4 /dev/nvme1n1 - Mounts it:
mount /dev/nvme1n1 /var/lib/kubelet/pods/.../mount - Pod's container now sees
/data(mounted volume)
Step 10: Container Starts
The container starts and can now read/write to /data (the persistent volume).
Why StorageClass Parameters Matter for Performance
Different workloads need different parameters:
Database Workload
Why: Databases need consistent, low-latency I/O. Transactions require guaranteed performance.
Cache/Session Store Workload
Why: Cache misses are acceptable. Doesn't need database-level guarantees.
Backup/Archive Workload
Why: Archive rarely accesses data. Cheapest option makes sense. Latency irrelevant.
Shared File System (logs, uploads)
Why: Need multi-node access (ReadWriteMany). EBS won't work.
Failure Modes and Troubleshooting
Failure 1: Provisioner Not Found
Symptom:
Cause:
- CSI driver not installed
- Provisioner name misspelled
- Driver pod crashed or not running
Fix:
Failure 2: Parameters Invalid
Symptom:
Cause:
- Parameter value not valid (io3 doesn't exist)
- Parameter not supported by provisioner version
Fix:
- Check AWS documentation for valid volume types
- Update StorageClass with correct parameter
Summary: StorageClass as Infrastructure Code
A StorageClass is infrastructure as code:
Design Pattern: Multiple Classes
Production clusters typically have multiple StorageClasses:
Developers choose the class that matches their workload's requirements.
Next File: Chapter 37 File 02 covers reclaim policies (what happens when a PVC is deleted).