Dynamic Provisioning: Laying the Groundwork for CSI

K8s Guru
3 min read
Dynamic Provisioning: Laying the Groundwork for CSI

Introduction

PersistentVolumes were powerful but clunky in early Kubernetes—operators pre-provisioned cloud disks and mapped them manually. Kubernetes 1.4 introduced StorageClasses and dynamic provisioning, enabling clusters to request volumes on demand. These ideas foreshadowed the Container Storage Interface (CSI) that would formalize pluggable storage in 2017.

In practice, this was the moment storage stopped being “a ticket to the ops team” and became something a developer could ask for declaratively. It also created a new operational surface area: quotas, reclaim policies, and the uncomfortable truth that storage mistakes are usually irreversible.

Historical note: the examples here reflect the 2016-era API (for example storage.k8s.io/v1beta1). If you’re applying this today, keep the concepts but use the current API versions and provisioner docs for your cluster.

StorageClasses 101

  • Named Policies: Define classes (fast, standard, encrypted) with provisioner names and parameters.
  • Provisioner Plugins: Cloud-specific provisioners (GCE PD, AWS EBS, Ceph RBD) live out-of-tree but expose a common interface.
  • PVC Binding: When a PersistentVolumeClaim references a StorageClass, Kubernetes requests a new volume that matches size and access mode.
  • Reclaim Policy: Set to Delete or Retain, controlling whether the backing disk persists after PVC deletion.

Example StorageClass + PVC

apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
  zone: us-central1-b
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: web-data
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: fast

External Provisioners

  • FlexVolume & External Controllers: Vendors shipped Docker containers that watch PVCs and call their storage APIs.
  • Lifecycle Hooks: Create/Delete operations were automated; resize and snapshot remained manual.
  • Security: Provisioners ran with storage credentials via Secrets, often in the kube-system namespace.

Practical gotchas (especially in early clusters)

  • Reclaim policy surprises: Delete is convenient until someone deletes a PVC and discovers it also deleted the backing disk.
  • Zone/region constraints: a volume created in us-central1-b can strand a workload if the scheduler later places the Pod elsewhere.
  • Access mode misunderstandings: ReadWriteOnce worked for most stateful apps, but shared writers required different storage (or a different design).
  • Quota-driven failures: dynamic provisioning makes storage “easy to ask for” and therefore easier to exhaust—watch per-zone limits and account quotas.

CSI on the Horizon

  • Community Discussions: SIG Storage initiated CSI design to replace in-tree plug-ins with a unified gRPC spec.
  • Goals: Decouple Kubernetes release cadence from storage drivers, standardize features like snapshotting and expansion, and share drivers across orchestrators.
  • Alpha Prototypes: 2016 saw early demos of CSI-inspired provisioners though the spec would finalize later.

Operational Guidance

  • Label StorageClasses by workload tiers; default StorageClass (metadata.annotations.storageclass.kubernetes.io/is-default-class) simplifies onboarding.
  • Monitor provisioner logs for quota errors—cloud providers often enforce per-zone limits.
  • Document reclaim policies to avoid accidental data loss when developers delete PVCs.
  • For on-premises environments, consider NFS, Gluster, or Ceph provisioners to mimic cloud-like automation.

Conclusion

Dynamic provisioning transformed persistent storage from a manual burden into a declarative resource. Kubernetes operators in 2016 gained self-service volumes, while SIG Storage laid the foundations for the CSI standard that would unlock an even richer ecosystem of drivers.