Using Longhorn for Containerized VM Storage in Harvester 1.x
Provision persistent Harvester VM storage with the built-in Longhorn integration, StorageClass, and PVC workflow.
05 Oct 2025, 11:30 UTC

Problem: VM storage still feels like manual block device management
You create a virtual machine in Harvester, but the disk does not appear after the VM starts. The storage was configured as a local path or a raw device on a single node, so moving the VM to another host means rebuilding the disk or accepting downtime. Harvester 1.x includes built-in integration with Longhorn, a containerized storage system for Kubernetes. The useful takeaway: instead of carving block devices by hand, you can define a StorageClass backed by Longhorn and let the VM claim a persistent volume through a standard Kubernetes PVC.
How the pieces fit together
Harvester runs KVM virtual machines on top of Kubernetes. Longhorn is installed as a containerized storage provider that exposes a CSI driver. CSI, or Container Storage Interface, is the plugin standard that lets Kubernetes provision storage without knowing the underlying hardware details. When you create a StorageClass named harvester-longhorn, the Longhorn provisioner creates a volume whenever a PVC asks for it. A PVC, or PersistentVolumeClaim, is a request for storage that can be attached to a VM’s volume specification. Longhorn then handles replication across nodes, snapshots, and rebuilding volumes after a node failure.
Version assumption: this applies to Harvester 1.0.0 and later. Earlier releases do not include the Longhorn integration.
Worked example: StorageClass and VM manifest
Prerequisites: access to a Harvester 1.x cluster with the Longhorn operator running. You need permissions to create StorageClasses and virtual machines, typically cluster-admin or delegated storage admin rights.
Step 1: Confirm Longhorn is running
Run from a workstation or admin node with kubectl configured:
kubectl get pods -n longhorn-system
Expected: pods such as longhorn-manager, longhorn-driver, and longhorn-ui are Running. If the namespace is empty or pods are CrashLoopBackOff, do not proceed until the Longhorn operator is healthy.
Step 2: Create the StorageClass
kubectl apply -f - <
Risk: on a single-node cluster, the default replica count of three will prevent volumes from becoming available. Reduce numberOfReplicas to match your node count.
Step 3: Define the VM with a volume claim template
Example manifest. Replace values in angle brackets with your own:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name:
namespace:
spec:
running: true
template:
metadata:
labels:
kubevirt.io/vm:
spec:
domain:
resources:
requests:
memory: 2Gi
volumes:
- name: rootdisk
persistentVolumeClaim:
claimName: root-pvc
volumeClaimTemplates:
- metadata:
name: root-pvc
spec:
storageClassName: harvester-longhorn
accessModes: ['ReadWriteOnce']
resources:
requests:
storage: 10Gi
Apply with kubectl apply -f .
Step 4: Verify binding
kubectl get pvc -n
Expected: root-pvc shows STATUS: Bound. If it stays Pending, check the Longhorn CSI pod logs and events with kubectl describe pvc root-pvc -n . You can also open the Longhorn UI and confirm a volume exists with the replica count you specified.
Trade-offs and limitations
- Longhorn replication defaults to three replicas. On a single-node Harvester installation, explicitly set
numberOfReplicas: "1"or the PVC will remain pending. - Containerized storage adds an I/O path through the CSI driver and Longhorn engine. Some reports suggest a small latency overhead compared with raw block devices, but this figure is unverified for your hardware and workload. Run your own
fiobenchmark inside the VM if latency is a hard requirement. - If the Longhorn CSI driver is uninstalled or misconfigured, new PVCs fail and existing volumes may become inaccessible. Treat Longhorn as a critical control-plane dependency for VM storage.
Rollback
Creating the StorageClass and VM changes cluster state. To remove the example:
kubectl delete vm -n
kubectl delete storageclass harvester-longhorn
Warning: deleting the StorageClass does not delete existing volumes, but it prevents new dynamic provisioning. Delete PVCs only if you intend to discard the data.
Closing
Longhorn integration turns VM disk management into a declarative Kubernetes operation. Start by confirming the Longhorn pods are running, create a StorageClass with a replica count suited to your cluster size, and attach a PVC to the VM spec. Verify the PVC reaches Bound before relying on the VM for production workloads.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.