Rancher’s Persistent Storage isn’t just about where your data lives, it’s about how Kubernetes decides to provision that storage for your applications, and the most critical piece of that puzzle is the StorageClass.
Let’s see a basic StorageClass in action. Imagine we’re setting up a PostgreSQL database that needs persistent storage.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
reclaimPolicy: Retain
mountOptions:
- debug
volumeBindingMode: Immediate
When a Pod requests a PersistentVolumeClaim (PVC) that specifies storageClassName: fast-ssd, Kubernetes doesn’t just magically create storage. It looks for a StorageClass named fast-ssd and then invokes the provisioner specified. In this case, kubernetes.io/aws-ebs tells Kubernetes to talk to the AWS EBS CSI driver. The parameters are then passed directly to that driver. type: gp3 tells the AWS EBS driver to create a gp3 volume, and fsType: ext4 specifies the filesystem to be formatted on that volume. reclaimPolicy: Retain means that when the PVC is deleted, the underlying EBS volume will not be deleted, allowing you to recover data if needed. volumeBindingMode: Immediate means that the PVC will be bound to a PV as soon as the PVC is created, even if no Pod is currently requesting it.
The core problem Rancher’s StorageClass abstraction solves is decoupling the application’s need for storage from the specific underlying infrastructure providing that storage. Instead of an application developer needing to know how to create an AWS EBS volume, a GCP Persistent Disk, or an NFS share, they simply request a StorageClass by name. Rancher, in conjunction with Kubernetes, then handles the complex provisioning logic. This allows administrators to define a set of pre-configured, reliable storage options that developers can easily consume.
Internally, when a PVC requests a specific StorageClass, Kubernetes finds that StorageClass object. It then identifies the provisioner field, which is typically a CSI (Container Storage Interface) driver or an in-tree provisioner (though in-tree provisioners are being deprecated). This provisioner is a piece of software responsible for interacting with the actual storage backend (like AWS EBS, Ceph, NFS, etc.) to create and manage PersistentVolumes. The parameters are key-value pairs that are passed directly to the provisioner, allowing for fine-grained control over the storage being provisioned (e.g., IOPS, throughput, disk type, encryption).
The reclaimPolicy is crucial for managing the lifecycle of your storage. Delete (the default) means the underlying storage resource (like an EBS volume) is deleted when the PVC is deleted. Retain keeps the storage resource, which is useful for data preservation but requires manual cleanup. Recycle (deprecated) would scrub the volume, but Retain is generally preferred. volumeBindingMode dictates when the provisioning and binding to a PV actually happens. Immediate binds as soon as the PVC is created, which can lead to PVs being created in a zone that doesn’t match the Pod’s node if the Pod isn’t scheduled yet. WaitForFirstConsumer delays provisioning until a Pod actually requests the PVC, ensuring the PV is provisioned in a compatible zone or node.
Most people don’t realize that the parameters field is entirely provisioner-dependent. What you can specify for kubernetes.io/aws-ebs (like type: gp3, iops, throughput) will be completely different from what you’d specify for kubernetes.io/gce-pd (like type: pd-ssd, replication-type) or a Ceph provisioner (like clusterID, pool). This means your StorageClass configuration is tightly coupled to the specific storage driver you’re using, and you need to consult the documentation for that driver to know what parameters are available and meaningful.
Once you’ve got your StorageClasses defined, the next step is to ensure your applications are actually requesting them via PersistentVolumeClaims.