Installation¶
VirtFoundry installs the control plane only (API, worker, UI, optional MySQL). Virtual machines, extra networks, and disk imports rely on platform components that must already exist on the cluster — or be installed before helm install.
For minimum vs production layouts (what works for VPC / public / snapshots on a home router), see Deployment topologies.
Prerequisites overview¶
| Component | Required? | Role in VirtFoundry |
|---|---|---|
| Kubernetes 1.28+ | Yes | Runs all workloads |
| Helm 3.x | Yes | Installs the chart |
| KubeVirt | Yes | Hypervisor — VMs, start/stop, console, VM snapshots |
| Multus CNI | Yes | Secondary NICs — tenant VPCs, isolated L2, public VM network |
| CDI | Yes for ISO/import templates; optional for container-disk-only | Imports ISOs and blank boot disks via DataVolume |
| Ingress or Gateway API + controller | One of them | Exposes UI and API on a hostname |
StorageClass (e.g. local-path) |
Yes for disks | PVCs for MySQL, VM volumes, ISO storage |
| CSI snapshotter + snapshot-capable CSI (e.g. Longhorn) | Only for volume snapshots UI | VolumeSnapshot CRDs + VolumeSnapshotClass; not provided by local-path |
| MetalLB (or cloud LB) | Bare metal only | When Services need external IPs |
Not bundled in the Helm chart by default
KubeVirt, Multus, and CDI are cluster-scoped platform operators. They are installed separately so you can pin versions, align with your distro, and upgrade them independently of VirtFoundry releases.
Why each platform component is needed¶
KubeVirt — required¶
VirtFoundry does not embed a hypervisor. The API and worker talk to KubeVirt CRDs:
VirtualMachine/VirtualMachineInstance— create, start, stop, delete VMsVirtualMachineSnapshot— VM snapshots (point-in-time of the guest; not the same as CSI volume snapshots)- VNC subresource — web console in the UI
Without KubeVirt, deploy and lifecycle operations fail immediately (kubevirt.enabled assumes the KubeVirt API is reachable).
Volume snapshots ≠ VM snapshots
The Volume Snapshots page creates Kubernetes VolumeSnapshot objects (snapshot.storage.k8s.io). That API is not installed by KubeVirt and is not available with only local-path. Without CSI external-snapshotter + a snapshot-capable StorageClass (Longhorn, Ceph RBD, cloud CSI, …), the UI returns the server could not find the requested resource. Use VM Snapshots on lab/local-path clusters, or install a CSI snapshot stack for volume snapshots. Details: Configuration — Snapshots.
Verify:
kubectl get pods -n kubevirt
kubectl get crd virtualmachines.kubevirt.io
Multus CNI — required¶
VirtFoundry models CloudStack-style networking: tenants, VPCs, security groups, and an optional shared public network. That requires more than the default pod CNI:
| Feature | How VirtFoundry uses Multus |
|---|---|
| Tenant VPC / private networks | Creates NetworkAttachmentDefinition (NAD) per network on an isolated bridge |
| Public / routable VM IPs | Secondary NIC on a bridge or macvlan NAD + cloud-init addressing |
| Security groups | Kubernetes NetworkPolicy on the pod network; extra NICs use Multus interfaces |
The hypervisor driver attaches Multus networks to VM launcher pods (v1.multus-cni.io/default-network and additional NADs). VPCs, custom networks, and public IP pools do not work without Multus.
Pod-only VMs (no network_ids, public network disabled) still use KubeVirt’s masquerade interface, but the product expects Multus for full IaaS functionality.
Verify:
kubectl get pods -n kube-system -l app=multus
kubectl get crd network-attachment-definitions.k8s.cni.cncf.io
CDI — required for ISO and import workflows¶
CDI provides DataVolume resources. VirtFoundry uses CDI when:
- Registering an ISO template (HTTP import of an
.isointo a PVC) - Creating a blank boot disk for install-from-ISO (e.g. Windows eval)
- Waiting for import completion before a VM can boot from ISO
Container-disk templates (image URL pointing at a registry-hosted disk image) can work without CDI — KubeVirt pulls the image directly as a containerDisk.
| Template / deploy path | CDI needed? |
|---|---|
| Linux cloud image (container disk) | No |
| ISO template or install-from-ISO | Yes |
| Attaching an existing imported volume | Yes (volume created via CDI) |
If you only use container-disk templates, you can skip CDI initially; enable it before using ISO features.
Verify:
kubectl get pods -n cdi
kubectl get crd datavolumes.cdi.kubevirt.io
Installing platform components¶
The chart can optionally trigger install hooks (platform.multus.install, platform.cdi.install, KubeVirt job). By default these are off — most clusters install platform software once, outside VirtFoundry upgrades.
Recommended: use the helper scripts (idempotent) from a chart clone:
export KUBECONFIG=/path/to/kubeconfig
./scripts/setup/kubevirt.sh # KubeVirt operator + CRDs
./scripts/setup/multus.sh # Multus DaemonSet
./scripts/setup/cdi.sh # CDI operator
Or install from upstream docs and verify CRDs before proceeding.
Order: Multus and storage class first → KubeVirt → CDI (CDI depends on KubeVirt CRDs).
Install VirtFoundry from Helm repository¶
After platform prerequisites are healthy:
helm repo add virtfoundry https://virtfoundry.github.io/helm-charts
helm repo update
helm install virtfoundry virtfoundry/virtfoundry \
--namespace virtfoundry-system \
--create-namespace \
--set secrets.rootPassword='change-me' \
--set secrets.jwtSecret='change-me-long-random'
Pin a release:
helm install virtfoundry virtfoundry/virtfoundry --version 1.4.1 \
--namespace virtfoundry-system \
--create-namespace \
--set secrets.rootPassword='change-me' \
--set secrets.jwtSecret='change-me-long-random'
Images default to ghcr.io/virtfoundry/core:1.4.1 and ui:1.4.1.
Install from git clone¶
git clone https://github.com/virtfoundry/helm-charts.git
cd helm-charts
helm install virtfoundry ./charts/virtfoundry \
--namespace virtfoundry-system \
--create-namespace \
--set secrets.rootPassword='change-me' \
--set secrets.jwtSecret='change-me'
Validate templates:
make lint
First login¶
Default bootstrap credentials (override with secrets.rootPassword):
- User:
root - Password: value of
secrets.rootPassword(default in chart values:virtfoundry)
API base path: /api/v1 on the same hostname as the UI.
Next steps¶
- Configuration — Helm values and networking
- Helm repository — publishing and consuming chart releases