17.8 Volume Expansion: Growing a PVC Online
Right, so you’ve got your PVC, it’s happily bound to a PV, and your application is humming along. Then you get the dreaded No space left on device error. Classic. The old you would have to bring the whole operation to a grinding halt: scale down the app, fiddle with the underlying storage, cross your fingers, and hopefully bring it all back online without data loss. A total party.
Thankfully, the Kubernetes gods have bestowed upon us the gift of online volume expansion. This is the magic trick of letting your PVC grow while it’s still mounted and actively written to by a pod. No downtime. It’s genuinely cool, and I’m not often impressed.
But—and you knew there was a ‘but’ coming—this isn’t magic fairy dust. It’s a carefully orchestrated series of handshakes between Kubernetes and your underlying storage system, and every link in that chain needs to be ready to play ball.
The Prerequisites (The “Why It Might Not Work” Checklist)
Before you even think about running a kubectl patch command, you need to check three boxes. Miss one, and this whole operation will fail silently, leaving you wondering what you did wrong.
The StorageClass Must Allow It. This is the big one. The
allowVolumeExpansionfield needs to be set totrue. If the person who provisioned the storage class was feeling restrictive (or just forgot), you’re out of luck. You’ll have to create a new, larger PVC and migrate data, the old-school way.apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: my-expandable-storage provisioner: pd.csi.storage.gke.io allowVolumeExpansion: true # <-- This is the golden ticketThe Underlying Provisioner Must Support It. Kubernetes is just the conductor; the storage driver (CSI) is the orchestra. Your specific CSI driver for AWS EBS, GCP PD, Azure Disk, Ceph RBD, etc., must implement the
CONTROLLER_EXPAND_VOLUMEcapability. Most major cloud providers and modern open-source drivers do, but if you’re running something obscure or ancient, check its documentation.The File System Must Support It. This is the most common gotcha. You can expand the block device all day long, but the file system on top of it (typically ext4 or xfs) needs to be expanded too. This is done via a
resize2fsorxfs_growfsoperation. The kubelet handles this automatically on the node where the pod is running, but only for file system types that support online expansion. This is why it “just works” most of the time, but it’s the reason the pod needs to be running and mounted.
The How-To (The Actual “Doing It” Part)
The process itself is almost absurdly simple. You just patch the PVC with a new, larger size. Kubernetes and the storage driver handle the rest.
# Find your PVC
kubectl get pvc
# Let's say it's called 'my-data-pvc' and is currently 10Gi
kubectl patch pvc my-data-pvc -p '{"spec":{"resources":{"requests":{"storage":"15Gi"}}}}'
Now, watch the magic happen. Use kubectl get pvc my-data-pvc -w to watch the status. You’ll see something beautiful:
NAME STATUS VOLUME CAPACITY ACCESS MODES
my-data-pvc Bound pvc-abc123... 10Gi RWO
my-data-pvc Bound pvc-abc123... 15Gi RWO # <-- Capacity updated!
The status went from Bound to FileSystemResizePending for a brief moment? That’s perfect. It means the underlying volume was resized and the kubelet on the node is now aware it needs to expand the file system on its next scheduled sync (usually every minute or so). Once that’s done, the capacity updates and the status returns to Bound.
The Rough Edges and Pitfalls
Here’s where my “brilliant friend” voice tells you the stuff the manual glosses over.
- Pod Restart Might Be Required (Sometimes): Wait, I thought this was online? It is… mostly. The file system resize happens live. However, some older storage drivers or certain volume modes (
Blockinstead ofFilesystem) might require restarting the pod to trigger the kubelet’s resize operation. It’s rare with modern cloud drivers, but be prepared for it. - The Application Might Need a Nudge: This is the most important insight. Kubernetes expands the disk, but your application might still be looking at the old size. A database like PostgreSQL won’t automatically know it now has more space to create new data files. A Java application might need its JVM restarted to see the new available space. You are responsible for informing your application that its world just got bigger. Often, this means restarting the pod, which is still infinitely better than a full migration.
- Shrinking is a Fantasy: Let’s be clear: you can never, ever shrink a PVC. The
spec.resources.requests.storagefield is a one-way ratchet. The risk of data loss is catastrophic. If you need a smaller volume, your only path is the migration dance: create a new PVC, copy data, update your pod spec, and delete the old one. It’s a pain, but it’s a pain for a very good reason.
So there you have it. Online volume expansion is a killer feature that turns a nightmare operational task into a simple API call. Just make sure your storage class, driver, and file system are all on the same page before you rely on it. Now go patch that PVC and give your app some breathing room.