Create a Local VM on Linux (QEMU/libvirt)
On a Linux host you can run a meltcloud Nest or Machine as a local VM using QEMU/KVM, managed with libvirt.
VM Settings
| Setting | Nest | Machine |
|---|---|---|
| Architecture | host arch (amd64/arm64) | host arch (amd64/arm64) |
| vCPU | 4+ | 2+ |
| RAM | 10 GiB+ | 4 GiB+ |
| Disk | ≥ 200 GiB | ≥ 30 GiB (depends on the amount of container images) |
| Networking | Default (NAT) | Default (NAT) |
| Nested virtualization | not required | optional, required for Elastic Node Pools |
| Boot media | Nest installer .iso | Enrollment Image .iso |
Prerequisites
Install packages
Install libvirt and qemu-system-x86 for your distro. The following installs it on Ubuntu 24.04+:
sudo apt install qemu-system-x86 libvirt-daemon-system ovmfAdd your user to the libvirt group so you can manage VMs without root:
sudo usermod -aG libvirt $USERLog out and back in for the group change to take effect.
Start the default network
libvirt ships a default NAT network that provides DHCP and internet access. Make sure it is active:
sudo virsh net-start default
sudo virsh net-autostart defaultCopy the ISO
Create a directory for VM images and copy your .iso into it:
# placed under /var/lib/libvirt so libvirt can traverse into it
sudo mkdir -p /var/lib/libvirt/melt-vms
sudo chown $USER:kvm /var/lib/libvirt/melt-vmsCopy the ISO you need: the Nest installer if you're setting up a Nest, or the Enrollment Image if you're enrolling a machine:
cp /path/to/nest-installer-v*-amd64.iso /var/lib/libvirt/melt-vms/cp /path/to/enrollment-image-amd64.iso /var/lib/libvirt/melt-vms/Create the VM
VMDIR=/var/lib/libvirt/melt-vms
ISO_PATH=$VMDIR/nest-installer-v*-amd64.iso
# create the disk (adjust size as needed, minimum 200 GiB; qemu's G suffix = GiB)
qemu-img create -f qcow2 $VMDIR/melt-nest.qcow2 200G
# write the VM definition
cat > $VMDIR/melt-nest.xml << EOF
<domain type='kvm'>
<name>melt-nest</name>
<!-- RAM: 10 GiB minimum -->
<memory unit='GiB'>10</memory>
<!-- CPU: 4+ vCPUs recommended -->
<vcpu>4</vcpu>
<os firmware='efi'>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
<boot dev='cdrom'/>
</os>
<features>
<acpi/>
</features>
<cpu mode='host-passthrough'/>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<!-- adjust path if you changed the qemu-img command above -->
<source file='$VMDIR/melt-nest.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='cdrom'>
<source file='$ISO_PATH'/>
<target dev='sda' bus='sata'/>
<readonly/>
</disk>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
</devices>
</domain>
EOF
# define, start, and connect to the console
virsh define $VMDIR/melt-nest.xml
virsh start melt-nest --consoleVMDIR=/var/lib/libvirt/melt-vms
ISO_PATH=$VMDIR/enrollment-image-amd64.iso
# change the name to create multiple machines (e.g. worker1, worker2)
VM_NAME=worker1
# create the disk (adjust size as needed, minimum 30 GiB; qemu's G suffix = GiB)
qemu-img create -f qcow2 $VMDIR/$VM_NAME.qcow2 30G
# write the VM definition
cat > $VMDIR/$VM_NAME.xml << EOF
<domain type='kvm'>
<name>$VM_NAME</name>
<!-- RAM: 4 GiB minimum -->
<memory unit='GiB'>8</memory>
<!-- CPU: 2+ vCPUs -->
<vcpu>2</vcpu>
<os firmware='efi'>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
<boot dev='cdrom'/>
</os>
<features>
<acpi/>
</features>
<cpu mode='host-passthrough'/>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<!-- adjust path if you changed the qemu-img command above -->
<source file='$VMDIR/$VM_NAME.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='cdrom'>
<source file='$ISO_PATH'/>
<target dev='sda' bus='sata'/>
<readonly/>
</disk>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
</devices>
</domain>
EOF
# define, start, and connect to the console
virsh define $VMDIR/$VM_NAME.xml
virsh start $VM_NAME --consoleExit the console with Ctrl+5. To reconnect later:
virsh console melt-nestTo clean up a VM:
virsh destroy melt-nest
virsh undefine melt-nest --nvramNext Steps
- Nest: follow the on-screen TUI installer.
- Machine: after it boots from the Enrollment Image it enrolls automatically and appears under Machines. Continue with Assign to a Machine Pool.
Troubleshoot
Nested virtualization not working
Nested virtualization is enabled by default on most recent Linux distributions. If it is not working, enable it manually:
# Intel
echo "options kvm_intel nested=1" | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel
# AMD
echo "options kvm_amd nested=1" | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_amd && sudo modprobe kvm_amdVerify with:
cat /sys/module/kvm_intel/parameters/nested # or kvm_amdThe VM must also use <cpu mode='host-passthrough'/> (already included in the XML definitions above).
Running on ARM (aarch64) hosts
This guide uses x86_64 examples, but ARM hosts work too. Adapt the following:
- Install
qemu-system-arminstead ofqemu-system-x86, andqemu-efi-aarch64instead ofovmf. - In the XML definitions, change
<type arch='x86_64'>hvm</type>to<type arch='aarch64'>hvm</type>. - Use the
arm64variants of the installer and enrollment ISOs (e.g.nest-installer-v*-arm64.iso).
Other issues
If the VM has trouble booting or enrolling, check the Enrollment Images – Troubleshooting section.
