Kubernetes Volume Expansion — Local-path vs Longhorn vs vSAN

The StorageClass is the abstraction layer between Kubernetes and the storage infrastructure underneath.

This is the same separation we have in VMware — storage admin owns the luns and datastores, VM admin picks which datastore to use. StorageClass is the Kubernetes equivalent of a datastore.

For production workloads we should always use a storage class that supports allowVolumeExpansion: true. For homelab learning — local-path is fine but if need more storage on a running app, what happens depends entirely on our storage class.

How StorageClasses Work

A StorageClass is a YAML object that defines how storage is provisioned. The provisioner field points to a CSI driver — and that driver is what talks to the actual storage backend.

PVC request
    └── StorageClass
            └── CSI Driver
                    └── Storage Backend
                            ├── local-path  →  node local disk
                            ├── Longhorn    →  replicated block storage
                            ├── vsphere-csi →  vSAN datastore
                            ├── netapp-csi  →  ONTAP SAN/NAS
                            └── ebs-csi     →  AWS EBS

The pod, PVC, and deployment YAML never change — only storageClassName differs.


The Problem — local-path Cannot Expand

We have mealie-logs at 100Mi and want to expand it to 200Mi. First check if the storage class supports it:

kubectl get storageclass

Output:

local-pathALLOWVOLUMEEXPANSION: false. Kubernetes will reject any attempt to resize.

If we try anyway to edit storage.yaml and apply,

 

Kubernetes simply ignores the size change. The PVC stays at 100Mi.


What Happens When a Volume Fills Up

With local-path and no expansion support — when logs fill the 100Mi:

  • App gets No space left on device on every write
  • Aps crash and pod goes CrashLoopBackOff

Check current usage inside the pod:

kubectl exec -it mealie-dcd97746f-5hpn4 -n mealie -- df -h

Monitor before it fills up — that is the only safe approach with local-path.


The local-path Workaround — Manual Resize

Since expansion is not supported, the only way is to recreate the PVC with a larger size. Data must be copied first or it will be lost.

Step 1 — scale down:

kubectl scale deployment mealie --replicas=0 -n mealie

Step 2 — copy data out if needed:

kubectl exec -it <old-pod> -n mealie --/bin/bash 
tar -czf /tmp/logs-backup.tar.gz /app/logs
kubectl cp mealie/<old-pod>:/tmp/logs-backup.tar.gz ./logs-backup.tar.gz

Step 3 — delete old PVC:

kubectl delete pvc mealie-logs -n mealie

Step 4 — update storage.yaml with new size and apply:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mealie-logs
  namespace: mealie
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 200Mi   # increased from 100Mi
  storageClassName: local-path
kubectl apply -f storage.yaml

Step 5 — scale back up:

kubectl scale deployment mealie --replicas=1 -n mealie

 

The Longhorn Way — Online Expansion

With Longhorn as the storage class, expansion is one line change and there is no downtime here. 

Edit storage.yaml — change the size:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mealie-logs
  namespace: mealie
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 200Mi   # changed from 100Mi
  storageClassName: longhorn

Apply it:

kubectl apply -f storage.yaml

Longhorn handles the resize online — pod keeps running, data is intact, no restart needed.

Verify:

kubectl get pvc mealie-logs -n mealie
kubectl describe pvc mealie-logs -n mealie

The vSphere / vSAN Way — Same as Longhorn

On VKS or vSphere with the CSI driver, the process is identical — just a different storageClassName.

The StorageClass definition is created once by the storage admin:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: vsphere-csi
provisioner: csi.vsphere.volume
parameters:
  storagePolicyName: vSAN-Default-Storage-Policy
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

App team uses it in their PVC:

storageClassName: vsphere-csi

Expansion works exactly the same way – edit the size, apply, vSAN handles it online via the CSI driver.

Summary

 local-pathLonghornvSphere CSI / NetApp
Online expansionNoYesYes
Downtime to resizeYesNoNo
Data loss riskYes if not backed upNoNo
ReplicationNoYesYes
Enterprise readyNoYesYes
How to expandDelete and recreateEdit size, applyEdit size, apply

 

(Visited 5 times, 1 visits today)

By Ash Thomas

Ash Thomas is a seasoned IT professional with extensive experience as a technical expert, complemented by a keen interest in blockchain technology.