Skip to main content

Chapter 6.3 - StorageClasses and Dynamic Provisioning

Learning Objectives

By the end of this chapter, you will be able to:

  • Understand what a StorageClass is
  • Configure dynamic provisioning
  • Create and use StorageClasses
  • Understand the different provisioners
  • Choose the right StorageClass based on the use case
  • Configure volume expansion

Introduction

Manually creating PersistentVolumes for each storage request is tedious. StorageClasses enable dynamic provisioning: Kubernetes automatically creates a PV when a PVC is created.


What Is a StorageClass?

A StorageClass describes the available storage classes and enables dynamic provisioning of PersistentVolumes. It defines:

  • The provisioner (how to create the volume)
  • The parameters (storage type, IOPS, etc.)
  • The default reclaim policy
  • Whether volume expansion is allowed

Creating a StorageClass

Example: AWS EBS StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Components:

  • name: StorageClass name
  • provisioner: Plugin that creates the volume
  • parameters: Provisioner-specific parameters
  • reclaimPolicy: Retain or Delete (default)
  • allowVolumeExpansion: Allows volume resizing
  • volumeBindingMode: Immediate or WaitForFirstConsumer

Provisioners

Cloud Provisioners

AWS EBS

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: aws-ebs-gp3
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
kmsKeyId: "arn:aws:kms:..."

Azure Disk

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-disk-ssd
provisioner: kubernetes.io/azure-disk
parameters:
storageaccounttype: Premium_LRS
kind: managed

GCE Persistent Disk

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gce-pd-ssd
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
replication-type: regional-pd

Local Provisioners

Local Storage

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

NFS

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: example.com/nfs
parameters:
server: nfs-server.example.com
path: /exports

Dynamic Provisioning

Create a PVC with StorageClass

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-dynamic
spec:
storageClassName: fast-ssd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

Process:

Result: Kubernetes automatically creates a PV matching the PVC.


Volume Binding Modes

Immediate

The PV is created and bound immediately when the PVC is created.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: immediate-sc
provisioner: kubernetes.io/aws-ebs
volumeBindingMode: Immediate

Advantages:

  • PVC available immediately
  • No waiting

Disadvantages:

  • Volume created even if unused
  • May create volumes on the wrong node

WaitForFirstConsumer

The PV is created only when a Pod uses the PVC.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: wait-sc
provisioner: kubernetes.io/aws-ebs
volumeBindingMode: WaitForFirstConsumer

Advantages:

  • Volume created on the correct node
  • Avoids unused volumes

Disadvantages:

  • Delay on first mount

Volume Expansion

Enable Expansion

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: expandable-sc
provisioner: kubernetes.io/aws-ebs
allowVolumeExpansion: true

Expand a Volume

  1. Modify the PVC to request more storage:
kubectl patch pvc pvc-dynamic -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
  1. Verify the expansion:
kubectl get pvc pvc-dynamic

Note: Expansion is supported only if:

  • allowVolumeExpansion: true in the StorageClass
  • The provisioner supports expansion
  • The filesystem supports expansion (ext4, xfs)

Complete Example

Step 1: Create the StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: production-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Step 2: Create the PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-pvc
spec:
storageClassName: production-ssd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi

Step 3: Use in a Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: app-data-pvc

Default StorageClass

Define a Default StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: default-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3

Result: PVCs without a storageClassName use this StorageClass.

PVC Without StorageClass

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# No storageClassName = uses the default StorageClass

Useful Commands

View StorageClasses

# List StorageClasses
kubectl get storageclass
kubectl get sc

# StorageClass details
kubectl describe storageclass fast-ssd

View PVCs and PVs

# List PVCs
kubectl get pvc

# View dynamically created PVs
kubectl get pv

# PVC details
kubectl describe pvc pvc-dynamic

Volume Expansion

# Expand a PVC
kubectl patch pvc pvc-dynamic -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'

# Check status
kubectl get pvc pvc-dynamic

Best Practices

1. Use Dynamic Provisioning

Prefer StorageClasses over manual provisioning for flexibility.

2. Choose the Right Volume Binding Mode

  • Immediate: For shared volumes (NFS)
  • WaitForFirstConsumer: For local volumes (EBS, Azure Disk)

3. Enable Expansion

Enable allowVolumeExpansion: true to allow resizing without recreation.

4. Appropriate Reclaim Policy

  • Retain: For important data
  • Delete: For temporary data

5. Monitoring

Monitor storage usage and costs.


Summary

In this chapter, you learned:

StorageClass: Describes storage classes and enables dynamic provisioning
Dynamic provisioning: Automatic PV creation when a PVC is created
Provisioners: Plugins that create volumes (EBS, Azure Disk, GCE PD, NFS, etc.)
Volume Binding Modes: Immediate (instant) or WaitForFirstConsumer (wait for Pod)
Expansion: Allows resizing an existing volume
Default StorageClass: Used when no storageClassName is specified
Advantages: Flexibility, automation, reduced manual management


Next Steps

Chapter 6.4: StatefulSets with Persistent Storage
Lab 6.3: StorageClasses and Dynamic Provisioning


Chapter created: December 2024