User-defined Playground

KubeVirt on K3s Playground

Multi-node K3s cluster with KubeVirt, CDI and the KubeVirt Manager web UI preinstalled. Run virtual machines next to containers.

KubeVirt on K3s playground: Multi-node K3s cluster with KubeVirt, CDI and the KubeVirt Manager web UI preinstalled. Run virtual machines next to containers.
Machines & network
4 VMs · 10 vCPU · 16GiB RAM
Playground host Internet NAT MASQUERADE local (bridge) 172.16.0.0/24 gw 172.16.0.1/24eth0eth0eth0eth0
VM
vCPU ·
eth0
/
oci://ghcr.io/omkar-shelke25/kubevirt-playground:dev-machine
VM
vCPU ·
eth0
/
oci://ghcr.io/omkar-shelke25/kubevirt-playground:cplane
VM
vCPU ·
eth0
/
oci://ghcr.io/omkar-shelke25/kubevirt-playground:node
VM
vCPU ·
eth0
/
oci://ghcr.io/omkar-shelke25/kubevirt-playground:node
About

A multi-node K3s cluster with KubeVirt preinstalled, ready to run virtual machines next to containers.

Machines

MachineIPRole
dev-machine172.16.0.5Workstation with kubectl, virtctl, helm, k9s, Docker and vm-vnc
cplane-01172.16.0.2K3s control plane, KubeVirt Manager on port 30080
node-01172.16.0.3K3s worker, runs VMs
node-02172.16.0.4K3s worker, runs VMs

Included

K3s, KubeVirt, CDI, KubeVirt Manager, virtctl, kubectl, helm, k9s, Docker, noVNC, and a Tokyo Night zsh terminal on every machine.

Components

ComponentNamespaceWhat it does
virt-operatorkubevirtInstalls and manages the other KubeVirt components
virt-apikubevirtAPI entry point for VM actions, serial console and VNC
virt-controllerkubevirtCreates a virt-launcher pod for every VM that starts
virt-handlerkubevirtDaemonSet, one pod per node, runs and monitors the VMs on that node
virt-launcher-<vm>VM's namespaceOne pod per running VM, runs QEMU
cdi-operatorcdiInstalls and manages the other CDI components
cdi-apiservercdiAPI for DataVolumes
cdi-deploymentcdiImports disk images into PVCs
cdi-uploadproxycdiReceives local images from virtctl image-upload
kubevirt-managerkubevirt-managerWeb UI behind the KubeVirt Manager tab

Tabs

TabOpens
IDEVS Code on dev-machine
ExplorerKubernetes resource explorer
KubeVirt ManagerWeb UI to create, start, stop and inspect VMs
VM ScreenA VM's display in the browser (run vm-vnc first)

Wait for the cluster

The playground opens once all three K3s nodes are Ready, but KubeVirt, CDI and KubeVirt Manager keep starting in the background for a few more minutes. Run these on dev-machine before creating any VM. Each command returns as soon as its component is ready.

Nodes:

kubectl get nodes

All three nodes must show Ready.

KubeVirt:

kubectl -n kubevirt wait kv kubevirt --for condition=Available --timeout=10m

CDI:

kubectl -n cdi wait cdi cdi --for condition=Available --timeout=10m

KubeVirt Manager:

kubectl -n kubevirt-manager rollout status deployment kubevirt-manager --timeout=10m

To see every component pod at once:

kubectl get pods -n kubevirt -o wide
kubectl get pods -n cdi

All pods must be Running with every container ready (for example 1/1).

Quick start

From dev-machine, create and start a small test VM:

kubectl apply -f https://kubevirt.io/labs/manifests/vm.yaml
virtctl start testvm
kubectl get vmi testvm -w

Wait for PHASE Running and READY True, then press Ctrl+C.

Serial console (exit with Ctrl+]):

virtctl console testvm

VM screen in the browser (VNC)

One command on dev-machine, with the VM running:

vm-vnc testvm

Then open the VM Screen tab. Press Ctrl+C in the terminal to stop.

For a VM in another namespace:

vm-vnc testvm my-namespace

vm-vnc does everything for you. It starts the KubeVirt VNC proxy and the browser bridge, and restarts the proxy after every session so reloading the tab reconnects. You never run virtctl vnc or websockify by hand.

vm-vnc stays in the foreground. Leave it running in one terminal tab and use another dev-machine terminal for other work.

Rules

  • A VM accepts only one VNC session at a time. Do not run virtctl vnc by hand while vm-vnc is running, or the two keep disconnecting each other.
  • Run one vm-vnc at a time. To switch VMs, press Ctrl+C and run vm-vnc with the other VM name.
  • Cloud images such as CirrOS and AlmaLinux show a text login prompt, not a desktop. If the screen is black, click inside it and press Enter.

Troubleshooting

SymptomFix
kubectl wait times outCheck the pods with kubectl get pods -n kubevirt and kubectl get pods -n cdi, then kubectl describe pod <name> -n <namespace> for the one that is not ready
VM default/testvm is not runningRun virtctl start testvm and wait for READY True
VM Screen tab shows an error pagevm-vnc is not running. Run it on dev-machine
Screen connects, then drops right awayAnother VNC session holds the VM. Run pkill -f 'virtctl vnc', then vm-vnc again
Address already in use on port 6080An old bridge is still running. Run pkill websockify, then vm-vnc again
Black screenClick inside the screen and press Enter

Limitations

iximiuz Labs playgrounds have no nested virtualization, so KubeVirt runs VMs with QEMU software emulation. Small images such as CirrOS boot in seconds, full distros take a few minutes.

containerDisk volumes are ephemeral. Anything written inside the VM is lost on every VM restart. Use a DataVolume on the local-path storage class for persistence.

Every playground includes
Learn more about playgrounds
Start
Settings