Quickstart (under 30 minutes)¶
Goal: UI login + first VM.
Who this is for, and what you need¶
VirtFoundry is a control plane on top of an existing Kubernetes cluster. It does not install Kubernetes, KubeVirt, Multus, CDI or storage for you. Before you start you need:
- A Kubernetes cluster you can
kubectlinto as cluster admin. - KubeVirt, Multus and CDI installed, and a default StorageClass (see Platform prerequisites).
- Linux nodes with
/dev/kvm(nested virtualization when the nodes are VMs). - Room for the control plane plus your VMs. The reference cluster has 2 nodes; give each a few CPU cores and several GB of RAM.
helm3 andkubectlon your machine.
No cluster? Use Kind on a Linux host (Docker, no VLAN). Kind does not work on macOS.
What has been tested¶
| Area | Verified |
|---|---|
| Cluster | 2 nodes, Cilium (kube-proxy replacement), Longhorn, MetalLB |
| Install | Quickstart below, clean cluster, release 0.11.3; Kind end-to-end in CI |
| Features | VM deploy, stop/start, console, snapshots, volumes, security groups, VKS cluster, Terraform provider |
| Not tested | EKS/GKE/AKS, k3s, Talos, other CNIs or storage, ARM nodes |
Anything in the "not tested" row may work, but nobody has checked. Report what you find. On a laptop, start with Kind (Docker, no VLAN). On a cluster that already has Kubernetes, KubeVirt, Multus, and CDI, continue below.
If you still need to install those platform components, see Platform prerequisites (official KubeVirt, Multus, CDI links) or the full Installation guide.
Homelab with Argo / Longhorn
Production-shaped layouts (Gateway API, Longhorn, snapshots): Deployment topologies. Public IPs without a VLAN: Kind or Topologies — public underlay.
0. Check prerequisites (~2 min)¶
kubectl get crd virtualmachines.kubevirt.io
kubectl get ds -A | grep -i multus || kubectl get pods -A | grep -i multus
kubectl get crd datavolumes.cdi.kubevirt.io
kubectl get storageclass
You need at least one default or known StorageClass. Prefer Longhorn (or any CSI with snapshots) for real disks.
local-path labs
Fine for a first UI click. Volume snapshots will not work without CSI external-snapshotter + a VolumeSnapshotClass. Use VM snapshots on lab StorageClasses, or install Longhorn (etc.) for volume snapshots.
1. Install VirtFoundry (~5 min)¶
helm repo add virtfoundry https://virtfoundry.github.io/helm-charts
helm repo update
# 1. CRDs (separate release: they hold your data, Helm never deletes them)
helm install virtfoundry-crds virtfoundry/virtfoundry-crds \
--version 0.12.0 \
--namespace virtfoundry-system --create-namespace
# 2. Operator + API + UI in one release
helm install virtfoundry virtfoundry/virtfoundry-platform \
--version 0.12.0 \
--namespace virtfoundry-system \
--set-string core.secrets.rootPassword='choose-a-strong-password' \
--set-string core.secrets.jwtSecret="$(openssl rand -hex 32)"
Advanced: three separate releases
Install the operator and the API/UI as their own releases when you want to upgrade them independently:
helm install virtfoundry-operator virtfoundry/virtfoundry-operator \
--version 0.12.0 --namespace virtfoundry-system
helm install virtfoundry virtfoundry/virtfoundry \
--version 0.12.0 --namespace virtfoundry-system \
--set secrets.rootPassword='choose-a-strong-password' \
--set secrets.jwtSecret="$(openssl rand -hex 32)"
Values then sit at the top level (secrets.*) instead of under core.*.
Wait until pods are ready:
kubectl -n virtfoundry-system get pods -w
kubectl get crd | grep virtfoundry.io
Helm --set is not optional for secrets
core.secrets.rootPassword (12+ chars) and core.secrets.jwtSecret (32+ chars) (secrets.* with the three separate releases) must be passed on this same helm install (or via -f, or replaced by secrets.existingSecret). The chart has no defaults for them and the install fails without them — see Secrets. They are chart values, not extra kubectl steps. Public CIDR and StorageClass do not need --set on a typical homelab: storage auto selects Longhorn when present; public stays off unless you enable it. Details: Chart values.
Optional — pin the CSI snapshot class (only if auto did not pick Longhorn):
helm upgrade virtfoundry virtfoundry/virtfoundry-platform -n virtfoundry-system \
--reuse-values \
--set core.platform.storage.snapshotClass=longhorn
Empty snapshotClass uses Longhorn when that is the resolved default class, otherwise the cluster default VolumeSnapshotClass.
2. Expose the UI (~5–10 min)¶
Pick one path.
kubectl -n virtfoundry-system port-forward svc/virtfoundry-ui 8080:80
Open http://127.0.0.1:8080
Copy-paste commands for both, and what your proxy must pass through: Expose the UI and API.
3. First login (~1 min)¶
- User:
root - Password: the
secrets.rootPasswordyou set (choose-a-strong-passwordabove)
Before other people use it, read Security and credentials: HTTPS, how to change the root password, and why daily work should not use root.
4. Deploy a first VM (~10 min)¶
In the UI (or API):
- Open SSH Keys and generate a key. Linux VMs need one, and a fresh install has none. The private key is shown once: save it.
- Open Templates — use a container disk template such as
cirros(no ISO download). - Open Service offerings — pick a small offering (or create one).
- Create a VM from that template + offering, with your SSH key and the default isolated network.
- Wait until the VM is Running (the panel shows its IP), then open Console (noVNC).
Networking
Full tenant VPC / Multus bridge demos need host bridges and often a public pool — Kind for a laptop, Topologies on real nodes. Container-disk VMs can still prove the control plane without a full L2 lab.
5. Sanity checks¶
kubectl -n virtfoundry-system get deploy
kubectl get vf-instance -A
kubectl get vmsnapshot -A
kubectl get vm -A
API health (with port-forward or your hostname):
curl -fsS http://127.0.0.1:8080/api/v1/healthz
# {"status":"ok","service":"virtfoundry-iaas","hypervisor":"kubevirt"}
/health on the UI address is not the API
The UI proxy forwards only /api/ and /ws/. Any other path, including /health, falls back to the UI page and returns 200 without testing anything. Use /api/v1/healthz (0.11.3 and newer). On 0.11.2 and older, port-forward the API service instead: kubectl -n virtfoundry-system port-forward svc/virtfoundry-api 8081:8080 and curl http://127.0.0.1:8081/health.
Next¶
| Topic | Doc |
|---|---|
| What you can do after login | Features overview |
| Reach the console from outside the cluster | Expose the UI and API |
| Passwords, HTTPS, who can do what | Security and credentials |
| Full install + why each dependency | Installation |
| Min vs production layouts | Topologies |
| Laptop (kind, no VLAN) | Kind |
| Helm values (public net, snapshots, defaults) | Configuration · Chart values |
| Why VirtFoundry vs Proxmox | Why VirtFoundry |
| Traction / CNCF checklist | CNCF checklist |
Questions: GitHub Discussions.