Skip to content

7.07 Kubernetes Storage Classes

Abstract

StorageClass enables dynamic provisioning of Persistent Volumes in Kubernetes.

Instead of manually creating cloud disks and Persistent Volumes, a StorageClass lets Kubernetes automatically provision storage when a Persistent Volume Claim (PVC) is created.


Why Storage Classes Are Needed

In static provisioning, an administrator must manually:

  1. Create a disk in the storage backend
  2. Create a Persistent Volume (PV)
  3. Match it with a Persistent Volume Claim (PVC)
  4. Attach it to a Pod

This becomes difficult in large production clusters.

Warning

Static provisioning does not scale well when many teams and applications need storage frequently.

StorageClasses solve this by enabling dynamic provisioning.


Static Provisioning

In static provisioning, storage is created manually before the PVC can use it.

Example flow:

Admin creates cloud disk
        ↓
Admin creates PV
        ↓
User creates PVC
        ↓
PVC binds to existing PV
        ↓
Pod uses PVC

Example Google Persistent Disk creation:

gcloud beta compute disks create \
  --size 1GB \
  --region us-east1 \
  pd-disk

Example PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-vol1

spec:
  accessModes:
    - ReadWriteOnce

  capacity:
    storage: 500Mi

  gcePersistentDisk:
    pdName: pd-disk
    fsType: ext4

Note

Static provisioning requires manual coordination between cloud storage and Kubernetes PV definitions.


Dynamic Provisioning

Dynamic provisioning automatically creates storage when a PVC requests it.

Flow:

StorageClass exists
        ↓
User creates PVC with storageClassName
        ↓
Provisioner creates storage automatically
        ↓
Kubernetes creates PV
        ↓
PVC binds to PV
        ↓
Pod uses PVC

Success

Dynamic provisioning is the recommended approach for production Kubernetes storage.


What is a StorageClass?

A StorageClass defines:

  • which storage provisioner to use
  • storage type
  • disk performance class
  • replication settings
  • reclaim behavior
  • volume binding behavior

Example:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: google-storage

provisioner: kubernetes.io/gce-pd

parameters:
  type: pd-standard
  replication-type: none

Tip

The provisioner field tells Kubernetes which storage backend should create the volume.


Using StorageClass in PVC

To use a StorageClass, specify storageClassName in the PVC.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim

spec:
  accessModes:
    - ReadWriteOnce

  storageClassName: google-storage

  resources:
    requests:
      storage: 500Mi

When this PVC is created:

  1. Kubernetes detects storageClassName: google-storage
  2. StorageClass calls the provisioner
  3. A disk is created automatically
  4. A PV is created automatically
  5. PVC binds to the PV

Pod Using PVC

The Pod still uses the PVC normally.

apiVersion: v1
kind: Pod
metadata:
  name: random-number-generator

spec:
  containers:
  - name: alpine
    image: alpine
    command: ["/bin/sh", "-c"]
    args:
      - shuf -i 0-100 -n 1 >> /opt/number.out;
    volumeMounts:
    - mountPath: /opt
      name: data-volume

  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: myclaim

Note

StorageClass provisions the PV, but Pods still consume storage through PVCs.


StorageClass Parameters

Parameters depend on the storage provisioner.

Example for Google Persistent Disk:

parameters:
  type: pd-standard
  replication-type: none

Possible disk types:

Type Description
pd-standard Standard persistent disk
pd-ssd SSD persistent disk

Possible replication types:

Type Description
none Single-zone disk
regional-pd Regional replicated disk

Warning

Parameters are provider-specific. Always check the storage provider documentation.


Storage Tiers Example

You can create multiple StorageClasses for different performance needs.

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

Example

Use different StorageClasses to offer different storage service levels such as Silver, Gold, and Platinum.


Common Provisioners

Older in-tree provisioners included:

Provider Provisioner Example
Google Persistent Disk kubernetes.io/gce-pd
AWS EBS kubernetes.io/aws-ebs
Azure Disk kubernetes.io/azure-disk
Azure File kubernetes.io/azure-file

Modern Kubernetes recommends CSI provisioners.

Examples:

Provider CSI Provisioner
AWS EBS ebs.csi.aws.com
Azure Disk disk.csi.azure.com
GCP Persistent Disk pd.csi.storage.gke.io

Tip

For production clusters, prefer CSI-based StorageClasses instead of older in-tree provisioners.


Reclaim Policy

StorageClass can define what happens when a PVC is deleted.

reclaimPolicy: Retain

Common values:

Policy Meaning
Retain Keep volume and data
Delete Delete volume and backing storage

Danger

Delete may permanently remove cloud storage when the PVC is deleted.

Use Retain for critical data like databases.


Volume Binding Mode

Recommended production setting:

volumeBindingMode: WaitForFirstConsumer

This delays volume provisioning until a Pod using the PVC is scheduled.

Why it matters:

  • chooses correct zone
  • prevents zone mismatch
  • improves scheduling success

Success

WaitForFirstConsumer is strongly recommended for zonal cloud storage.


Production StorageClass Example

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: production-ssd

provisioner: pd.csi.storage.gke.io

parameters:
  type: pd-ssd
  replication-type: none

reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Note

This example uses a CSI provisioner, allows expansion, retains data, and waits for Pod scheduling before provisioning.


Production Best Practices

Recommended

  • Use dynamic provisioning with StorageClasses
  • Prefer CSI drivers
  • Use WaitForFirstConsumer
  • Use Retain for critical workloads
  • Create separate storage tiers such as silver, gold, platinum
  • Enable volume expansion if supported
  • Monitor storage usage and performance
  • Back up important volumes regularly

Do's

  • Use StorageClasses for production workloads
  • Use PVCs with storageClassName
  • Choose storage tiers based on workload needs
  • Use SSD-backed storage for latency-sensitive apps
  • Use replicated storage for critical workloads

Don'ts

  • Don't manually provision disks for every workload
  • Don't use old in-tree provisioners when CSI drivers are available
  • Don't use Delete reclaim policy for critical databases
  • Don't assume all provisioners support the same parameters
  • Don't ignore zone and region placement

Danger

Incorrect StorageClass configuration can cause failed volume provisioning, scheduling issues, or permanent data loss.


Quick Commands

List StorageClasses:

kubectl get storageclass

Short command:

kubectl get sc

Describe StorageClass:

kubectl describe storageclass google-storage

Create StorageClass:

kubectl apply -f sc-definition.yaml

Check PVC binding:

kubectl get pvc
kubectl get pv

Static vs Dynamic Provisioning

Feature Static Provisioning Dynamic Provisioning
Disk creation Manual Automatic
PV creation Manual Automatic
Uses StorageClass No Yes
Operational effort High Low
Production scalability Poor Good

Summary

Quote

  • StorageClass enables dynamic provisioning
  • PVCs request storage using storageClassName
  • Provisioners create storage automatically
  • Multiple StorageClasses can represent different storage tiers
  • Production clusters should use CSI drivers and WaitForFirstConsumer