pivirtd Daemon
Manages QEMU processes, VM lifecycle, networking interfaces, and storage disks under /var/lib/pivirt/.
This guide explains how pivirtd provisions and manages Talos Linux Kubernetes clusters, how the hypervisor stack is deployed and configured on host nodes, and how to perform cluster lifecycle operations (scaling workers, expanding control-plane HA, and safely removing nodes) using pivirtctl and talosctl.
The pivirtd hypervisor stack operates as a lightweight, zero-dependency QEMU/KVM daemon with embedded network and cloud metadata services:
flowchart TB
subgraph Host["Host (vm3)"]
subgraph Daemon["pivirtd"]
API["Unix socket API / gRPC"]
DHCP["Embedded DHCP Server (AF_PACKET)"]
META_SRV["Cloud Metadata Server (:8080)"]
end
OVS["Open vSwitch (br-provision)<br/>GW: 10.0.0.1/24 | Meta: 169.254.169.254"]
Daemon --> OVS
end
subgraph Cluster["Talos Cluster"]
CP["talos-cp-0 (Control Plane)<br/>- UEFI / OVMF Boot<br/>- IP: 10.0.0.10<br/>- Fetches config from 169.254.169.254"]
WORKERS["talos-worker-2, 3, 4 (Workers)<br/>- UEFI / OVMF Boot<br/>- IPs: 10.0.0.11, .12, .13<br/>- Fetches config from 169.254.169.254"]
end
OVS --> CP
OVS --> WORKERS
pivirtd Daemon
Manages QEMU processes, VM lifecycle, networking interfaces, and storage disks under /var/lib/pivirt/.
pivirtctl CLI
Host management CLI that communicates with pivirtd over Unix socket (/var/lib/pivirt/daemon/pivirtd.sock).
Open vSwitch (br-provision)
Provides VM bridge networking with gateway IP 10.0.0.1/24 and metadata routing.
Cloud Metadata Service
Listens on 10.0.0.1:8080. IPTables DNAT redirects http://169.254.169.254:80 requests to 10.0.0.1:8080.
Talos Linux OS
Boots via UEFI (OVMF_CODE.fd), receives kernel parameters via SMBIOS OEM strings (fw_cfg), and auto-configures via metadata.
pivirtd StackChoose one of the following deployment options to install or update pivirtd and pivirtctl on your host:
Use the provided automated deployment script to build and deploy to a target host:
Run Deployment Script:
./scripts/deploy-pivirtd.sh --host vm3.pilab.huVerify Daemon Service:
ssh vm3.pilab.hu "sudo systemctl status pivirtd"To compile and install the binaries manually:
Cross-Compile Binaries for Linux:
GOOS=linux GOARCH=amd64 go build -o bin/pivirtd ./apps/pivirtd/cmd/pivirtdGOOS=linux GOARCH=amd64 go build -o bin/pivirtctl ./apps/pivirtctl/main.goCopy Binaries to Target Host:
scp bin/pivirtd bin/pivirtctl vm3.pilab.hu:/tmp/ssh vm3.pilab.hu "sudo mv /tmp/pivirtd /tmp/pivirtctl /usr/local/bin/ && sudo chmod +x /usr/local/bin/pivirtd /usr/local/bin/pivirtctl"Restart the pivirtd Service:
ssh vm3.pilab.hu "sudo systemctl restart pivirtd"Follow these step-by-step instructions to initialize and launch a new Talos Linux VM instance on pivirtd:
Generate Talos Machine Configurations
Generate cluster configurations using talosctl:
talosctl gen config talos-cluster https://10.0.0.10:6443 --output-dir ./cluster-configCreate VM Directories and System Files
For each target VM (e.g., talos-worker-2):
/var/lib/pivirt/vms/talos-worker-2/worker.yaml to /var/lib/pivirt/vms/talos-worker-2/talos-configqemu-img create -f raw /var/lib/pivirt/vms/talos-worker-2/disks/system.raw 10Gcp /usr/share/OVMF/OVMF_VARS.fd /var/lib/pivirt/vms/talos-worker-2/nvram.fdDefine VM Specification (config.yaml)
Create /var/lib/pivirt/vms/talos-worker-2/config.yaml with SMBIOS OEM strings:
name: talos-worker-2uuid: 04a7851e-04bd-4544-970a-fa2b5198ef60sysInfo: type: smbios oemStrings: io.systemd.stub.kernel-cmdline-extra: "console=ttyS0,115200"os: type: hvm machine: q35 firmware: uefi efi: loader: readonly: true type: pflash path: /usr/share/OVMF/OVMF_CODE.fd nvram: path: /var/lib/pivirt/vms/talos-worker-2/nvram.fddevices: networkinterfaces: - type: openvswitch source: br-provision mac: 52:54:00:ab:cd:0f model: virtio disks: - deviceType: disk driver: name: qemu type: raw path: /var/lib/pivirt/vms/talos-worker-2/disks/system.raw target: bus: virtio dev: vdaStart the Virtual Machine via pivirtctl
Execute the start command:
sudo pivirtctl vm start talos-worker-2Manage post-deployment cluster changes such as scaling worker nodes, expanding control plane HA, or performing safe node decommissioning:
/var/lib/pivirt/vms/talos-worker-5/worker.yaml into /var/lib/pivirt/vms/talos-worker-5/talos-configsudo qemu-img create -f raw /var/lib/pivirt/vms/talos-worker-5/disks/system.raw 10Gsudo cp /usr/share/OVMF/OVMF_VARS.fd /var/lib/pivirt/vms/talos-worker-5/nvram.fdconfig.yaml with a unique UUID & MAC address.sudo pivirtctl vm start talos-worker-5worker.yaml from metadata, and joins Kubernetes automatically./var/lib/pivirt/vms/talos-cp-1/controlplane.yaml into /var/lib/pivirt/vms/talos-cp-1/talos-configsudo qemu-img create -f raw /var/lib/pivirt/vms/talos-cp-1/disks/system.raw 10Gsudo cp /usr/share/OVMF/OVMF_VARS.fd /var/lib/pivirt/vms/talos-cp-1/nvram.fdconfig.yaml with SMBIOS OEM strings.sudo pivirtctl vm start talos-cp-1kubectl get nodestalosctl -n 10.0.0.10 etcd membersFollow these steps to safely decommission a worker or control plane node:
Cordon and Drain Node in Kubernetes:
kubectl cordon <node-name>kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-dataDelete Node Object:
kubectl delete node <node-name>Reset Talos Node State (Optional):
talosctl -n <node-ip> resetStop Hypervisor VM:
sudo pivirtctl vm stop <vm-name>Delete VM Registration:
sudo pivirtctl vm delete <vm-name>pivirtctl Command Reference| Command | Action / Description |
|---|---|
sudo pivirtctl vm list |
List all VMs registered on the local hypervisor |
sudo pivirtctl vm info <vm> |
Display detailed VM runtime status and configuration |
sudo pivirtctl vm start <vm> |
Start a virtual machine instance |
sudo pivirtctl vm stop <vm> |
Cleanly shut down a virtual machine via ACPI |
sudo pivirtctl vm stop -f <vm> |
Force stop (SIGKILL) a virtual machine |
sudo pivirtctl vm reboot <vm> |
Reboot a virtual machine instance |
sudo pivirtctl vm delete <vm> |
Remove VM registration from pivirtd |