Skip to content

Storage configuration

Helm values for StorageClasses and snapshots. Overview of every other value: Configuration.

VirtFoundry does not ship a storage backend. It uses StorageClasses already present on your cluster (Longhorn, Ceph RBD, NFS, OpenEBS, local-path, cloud provider disks, etc.).

Preferred: Longhorn

Longhorn is the recommended StorageClass for VirtFoundry beyond a single-node throwaway lab: replicated block volumes, CSI volume snapshots, and disks that survive a worker loss. Keep local-path only for quick demos; set platform.storage.defaultClass=longhorn (and make longhorn the cluster default) as soon as you have two or more workers.

Default StorageClass (platform.storage)

Key Default Description
storage.defaultClass auto Longhorn if present, else cluster default, else local-path
storage.snapshotClass "" CSI VolumeSnapshotClass for volume snapshots; empty uses cluster default
storage.windowsBootSizeGi 32 Boot disk size when deploying from an ISO template
storage.windowsISOSizeGi 8 ISO import PVC size

List classes on the cluster, then point VirtFoundry at Longhorn (or another replicated CSI):

kubectl get storageclass
kubectl get volumesnapshotclass
platform:
  storage:
    defaultClass: auto       # or longhorn / ceph-rbd / local-path
    snapshotClass: ""        # empty → longhorn when default resolves to longhorn
    windowsBootSizeGi: 32
    windowsISOSizeGi: 8

Helm one-liner:

helm upgrade --install virtfoundry virtfoundry/virtfoundry \
  --set platform.storage.defaultClass=longhorn \
  --set platform.storage.snapshotClass=longhorn \
  ...

What uses which StorageClass

Workload Controlled by Notes
ISO import / install-from-ISO (CDI) platform.storage.defaultClass Blank boot disk + HTTP ISO DataVolume
VM template (API) storage_class on template or default above Per-template override in POST /vm-templates
Container-disk templates — Image pulled as containerDisk; no PVC for the OS image
Tenant volumes (/volumes UI) Cluster / app default Uses Kubernetes PVC creation; wire to defaultClass in a future release

Snapshots: VM vs volume

VirtFoundry exposes two different snapshot features. They use different Kubernetes APIs and have different cluster prerequisites.

Feature UI / API Kubernetes API Requires
VM snapshot /vm-snapshots, VM detail → Snapshots VirtualMachineSnapshot (snapshot.kubevirt.io) KubeVirt (already required)
Volume snapshot /snapshots VolumeSnapshot (snapshot.storage.k8s.io) CSI snapshot stack + a StorageClass whose CSI driver supports snapshots

Volume snapshots do not work with local-path.
rancher.io/local-path is not a CSI driver with snapshot support. Creating a volume snapshot on a lab cluster that only has local-path fails with:

create volumesnapshot: the server could not find the requested resource

That error means the cluster is missing the VolumeSnapshot CRDs (snapshot.storage.k8s.io), and even after installing them you still need a CSI backend that can actually take snapshots.

To enable volume snapshots, install all of the following on the cluster (VirtFoundry does not bundle them):

  1. CSI external-snapshotter — CRDs + snapshot-controller
    (kubernetes-csi/external-snapshotter)
  2. A CSI StorageClass with snapshot support — for example Longhorn (CNCF, Apache 2.0), Rook/Ceph RBD, or a cloud-provider CSI
  3. A VolumeSnapshotClass for that driver — either a cluster default (snapshot.storage.kubernetes.io/is-default-class: "true") or set platform.storage.snapshotClass (e.g. longhorn). Empty config omits volumeSnapshotClassName so Kubernetes uses the default class.

Verify before using the UI:

kubectl api-resources | grep volumesnapshot
kubectl get volumesnapshotclass
kubectl get storageclass

For point-in-time backup of a whole guest on a local-path / lab cluster, use VM snapshots instead of volume snapshots.

Per-template override (API)

When registering a template, set storage_class to use a different class for that image only:

{
  "name": "win2022-eval",
  "source_type": "iso",
  "image": "https://example.com/win.iso",
  "storage_class": "ceph-rbd"
}

If omitted, the API falls back to platform.storage.defaultClass from Helm.