🚀 How I Got KubeVirt Running on Talos Linux (And Why It’s Awesome)

A hands-on guide to mixing VMs and containers on a rock-solid Kubernetes-native OS

Posted by Rodin Frese on 22nd Mar 2025

Lately, I’ve been diving into running virtual machines inside Kubernetes—and yeah, it’s as cool as it sounds. One of the slickest ways to do this is with KubeVirt, which basically turns your Kubernetes cluster into a platform that can manage both containers and VMs. Pretty wild.

Now, I’m also a big fan of Talos Linux. If you haven’t used it before, it’s an ultra-minimal, immutable OS built specifically for Kubernetes. No SSH, no package manager—just API-driven infrastructure. It’s a little different, but once you get used to it, it feels incredibly clean.

So naturally, I wanted to see what it would take to get KubeVirt running on a Kubernetes cluster powered by Talos. Here’s how it went.


What You’ll Need

Before anything, make sure you have:

  • A Kubernetes cluster running on Talos (I used v1.28)

  • Access to the cluster via talosctl and kubectl

  • Optionally, the virtctl CLI for managing VMs

  • Nodes with virtualization enabled (Intel VT-x or AMD-V)

Not sure about your CPU? You can test it on a non-Talos machine with lscpu | grep Virtualization.


Step 1: Make Sure Your Talos Cluster is Ready

If you’re starting from scratch, I highly recommend checking out the Talos Quickstart guide. I had my setup running with a few VMs locally, but this works fine in the cloud or on bare metal too.


Step 2: Deploy the KubeVirt Operator

Once the cluster is up, installing KubeVirt is surprisingly straightforward.

First, grab the latest release:

export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | jq -r .tag_name)

Then deploy the operator and the KubeVirt custom resource:

kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml

This will spin up everything KubeVirt needs in the background.


Step 3: Verify That It’s Working

Give it a minute or two, then check:

kubectl get pods -n kubevirt

You should see virt-api, virt-controller, and virt-handler running. If anything’s stuck, check the logs—they’re usually pretty helpful.


Step 4 (Optional): Install virtctl

This little CLI tool makes interacting with VMs way easier.

To install it:

wget https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-linux-amd64
chmod +x virtctl-${VERSION}-linux-amd64
sudo mv virtctl-${VERSION}-linux-amd64 /usr/local/bin/virtctl

Step 5: Create Your First VM

Here’s the YAML I used to launch a Windows Server 2025:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: win2025-vm
  namespace: default
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/domain: win2025-vm
    spec:
      domain:
        cpu:
          cores: 4
        resources:
          requests:
            memory: 4Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: sata
            - name: virtiocontroller
              disk:
                bus: virtio
        features:
          acpi: {}
          apic: {}
          hyperv:
            relaxed: {}
            vapic: {}
            spinlocks:
              spinlocks: 8191
        firmware:
          bootloader:
            efi: {}
      terminationGracePeriodSeconds: 180
      volumes:
        - name: rootdisk
          containerDisk:
            image: /windows-server-2025:latest
        - name: virtiocontroller
          containerDisk:
            image: kubevirt/virtio-container-disk

Replace <your-container-registry>/windows-server-2025:latest with the actual container image you’ve built or obtained. This image should include:

  • A valid Windows Server 2025 ISO or pre-installed image

  • VirtIO drivers preloaded (or added via a second volume if needed)

  • Sysprep'd and configured for cloud-init or equivalent, if possible


Optional: Add a Service to Expose RDP

You can expose the VM via NodePort to access it over RDP:

apiVersion: v1
kind: Service
metadata:
  name: win2025-vm-service
spec:
  selector:
    kubevirt.io/domain: win2025-vm
  ports:
    - protocol: TCP
      port: 3389
      targetPort: 3389
      nodePort: 31389
  type: NodePort

Now you can RDP to your VM using node-ip:31389


đź’­ Final Thoughts

Honestly, I was surprised by how smoothly everything came together. Talos doesn’t let you tinker at the OS level—which feels restrictive at first—but once you embrace its Kubernetes-first mindset, it actually feels powerful, clean, and super intentional.

Pairing that with KubeVirt means I can now run VMs alongside containers on the same cluster. It's ideal for legacy apps, CI jobs, or just anything that doesn't fit neatly into a container. No more needing to spin up separate hypervisors or maintain parallel infrastructure—KubeVirt bridges that gap beautifully.

For the complete guide to installing KubeVirt on Talos Linux, check out: Install KubeVirt on Talos | Talos Linux

If you're exploring modern infrastructure and want a clean, GitOps-friendly way to mix virtual machines and containers, I highly recommend giving this setup a spin.