Skip to main content
Celum runs virtual machines on a supervisor through KubeVirt. A VM is created from an image in the image library — either cloned from a prepared golden disk or installed from an ISO — and provisioned on first boot by cloud-init (Linux) or sysprep (Windows).

Prerequisites

  • Permission: vm:Create on krn:celum:supervisor:<supervisor>:vm:*. The form’s dropdowns also need discovery:ListInstanceTypes, discovery:ListStorageClasses, and discovery:ListNamespaces.
  • KubeVirt installed on the supervisor. Its status is virt:GetStatus; installing it is virt:Install — see the platform onboarding wizard.
  • An image in the library with status ready. Creation is rejected against an image in any other state.
  • A storage class that can back the VM’s disks.
<supervisor> and <vm> are placeholders throughout. Substitute your own names.

What an image gives you

Two properties of the chosen image decide what the VM can later do:
Choose the access mode at image-import time, not at VM-create time. A VM built on a ReadWriteOnce image cannot be live-migrated later without rebuilding it from an RWX image.

Create it

1

Name and place it

Give the VM a name and pick its Project. The VM is created in the project’s namespace and inherits its addressing and isolation. Over the API the namespace comes from the request body and defaults to default.
2

Pick the image and instance type

Name, image, and instance type are the only strictly required fields. The instance type sets CPU and memory; disk size defaults to 20Gi when left empty. The storage class you pick also filters the image cards: a VM is cloned from an image’s golden volume, and a clone cannot cross storage classes.
3

Set up access

For Linux, supply SSH public keys and/or a password. For Windows, an admin password. See Console & access.Result: whatever you supply is written into the guest at first boot. Neither field is required and neither is validated, so a VM created with both empty boots perfectly and has no way in but the serial console.
4

Choose a network mode

Set at creation and not changeable later without recreating the VM — the one field on this form worth slowing down for.masquerade (NAT in the form), the default, is live-migratable and is the only mode the VM Identity Network is built for. bridge hands the guest the pod IP directly and gives up live migration and the identity network to do it. passt keeps both but needs a node prerequisite. Full comparison under Network mode.Result: leaving it alone is right unless you specifically need the guest to own the pod address.Two switches sit beside it. Reachable from outside the cluster (SSH / RDP) exposes the VM right after it is created, as the VM’s Expose action does; if that step fails the VM still exists and the form says why. It is not offered for an ISO install. Fixed IP address that stays when the VM moves appears once a project is picked: it is the VM Identity Network.
5

Add provisioning

Startup commands, a setup template (a cloud-init template), data disks, and labels — all optional. Labels are key=value tags kept on the VM to group and filter it in Workloads. To change them later, use Edit on the Catalog labels card of the VM’s Resources tab; see Catalog labels.Result: these become one boot script in a fixed order: the guest-agent install, then the template, then anything typed here. A command typed on this form runs after the template, never before it.
6

Create

The VM object is created and the disk clone or ISO install begins.Result: 201 {"status": "created"}. That means the objects were applied — not that the VM is running. Provisioning continues in the background, so the checks under Verify it worked are the ones that tell you it succeeded.
The namespace comes from the request body, and defaults to default. If you also pass ?namespace= on the URL it must name the same namespace, or the call is refused — the query parameter is what the authorization check reads, so a mismatch would mean authorizing against a project you hold while creating in one you do not.

Network mode

Set at creation and not changeable afterwards without recreating the VM.
Enabling the identity network with bridge or passt is accepted but logged as experimental — the claim address’s NAT path assumes the masquerade layout, so the address may not behave as intended. Use masquerade when you want a stable identity IP.
passt requires unprivileged user namespaces on the node. Talos hardening ships user.max_user_namespaces=0, and passt then dies with “Couldn’t create user namespace: EPERM” — the VM never starts, and nothing about the VM itself is wrong. A machine-config sysctl is needed before this mode works on a Talos supervisor.

VM Identity Network

An optional stable, BGP-routable address that follows the VM across live migrations, instead of the volatile pod IP. It requires:
  • an identity pool on the supervisor (identityPool is mandatory when the identity network is enabled), and
  • a ReadWriteMany image — an identity address is pointless without live migration, since surviving the migration cutover is its whole purpose.
The address is allocated before the VM object is created, so a bad pool, an exhausted pool, or a non-migratable image fails cleanly with nothing left behind.

Linux provisioning

Provisioning is delivered through cloud-init (or Ignition, for images that use it) as a single boot script.
Do not turn the guest agent off casually. Without it KubeVirt cannot report the guest OS or IP, cannot shut the VM down gracefully, and cannot freeze the filesystem for snapshots — and the listening-ports, processes, filesystems, and connectivity-check endpoints all return 404.
The agent install is placed first in the boot script, ahead of any template, so the VM reports its OS and address in seconds rather than after a long package install finishes.

Windows provisioning

A prepared Windows disk image is cloned. Provisioning is delivered on a sysprep CD:
  • Sysprep template — an autounattend.xml with template variables. Empty uses the built-in default with the universal virtio driver paths.
  • Setup script — a PowerShell script delivered as setup.ps1 and run once at first logon. This is the Windows equivalent of startup commands; put IIS, SQL, and tooling installs here.
Two Windows options default to on and rarely need touching:

Disk layout

Beyond the boot disk you can define, at creation time:
  • Data disks — additional blank disks, each formatted and mounted at a path you choose. A data disk can use its own storage class; otherwise it inherits the VM’s.
  • Root partitions (API only) — extra partitions carved out of the boot disk after the image’s own root partition, each with a mount path, size, and filesystem (ext4, xfs, or btrfs; ext4 by default). A partition with no size takes the remaining space and must be last. The form stopped offering them on 2026-10-07: a data disk does the same job and can be sized and tiered apart from the OS disk.
Both work for cloud-init and Ignition images. Disks can also be added later — see Storage & disks.

Ephemeral boot

Instead of cloning the golden into a per-VM disk, the VM can boot from a copy-on-write overlay over a shared, read-only golden. There is no clone, so boot takes seconds rather than minutes — and all writes are discarded when the VM stops.
Ephemeral boot is an API-only option — it is deliberately not in the create form. It requires an NFS-CSI-backed golden, because that is the only case where the read-only base can be shared cheaply. Use it for disposable and test VMs.

Verify it worked

The VM appears in the list at /s/<supervisor>/vms. Open it and check, in order:
1

It is running

Status reaches running. A clone-based boot on file storage can take a couple of minutes before this happens.
2

The guest agent connected

The VM reports its guest OS and internal IP. Until the agent connects, those fields stay empty and the introspection tabs have nothing to show.
3

The identity address is present

If you enabled the identity network, the VM shows an identity IP alongside its pod IP. It is stamped at create time but takes a moment to surface, so poll for it rather than treating an empty field as a failure — and read it back rather than computing it from the pool.

What commonly goes wrong

Lifecycle

Start, stop, migrate, snapshot, clone, move, and delete.

Networking

Publishing ports, gateways, and the identity network.

Storage & disks

Attaching, detaching, and snapshotting volumes.

Console & access

VNC, the guest agent, and in-guest introspection.