Andrew Mercer
on this page

Create KVM virtual machines

Part of the KVM overview. Install with kickstart or preseed, import an existing image, or build from a template.

Find a valid --os-variant:

osinfo-query os | grep -i debian

--os-type is deprecated; --os-variant is enough.

Install from an ISO with a kickstart (RHEL family)

Serve the kickstart file from the directory that contains it:

python3 -m http.server 8000
sudo virt-install --name vm01 --description "Test VM" --memory 2048 --vcpus 2 \
  --location ~/Downloads/rhel-9-x86_64-dvd.iso --os-variant rhel9.0 \
  --disk path=/var/lib/libvirt/images/vm01.qcow2,size=20,format=qcow2,bus=virtio \
  --network bridge=br0,model=virtio --autostart --graphics none \
  --console pty,target_type=serial \
  --extra-args "console=ttyS0,115200n8 inst.sshd inst.ks=http://192.0.2.50:8000/ks.cfg ip=dhcp"

Variations:

Need Change
Install from a network mirror --location http://mirror.example.com/os/x86_64/ instead of an ISO
Fixed MAC address --network bridge=br0,model=virtio,mac=52:54:00:aa:bb:01
Two disks / two NICs Repeat --disk / --network
Internal HTTPS server with a private CA Add inst.noverifyssl to --extra-args
Default NAT network --network network=default,model=virtio
Windows guest --cdrom with the ISO, --graphics vnc, --os-variant win2k22; --graphics none does not work

Install with a preseed file (Debian family)

sudo virt-install --name vm02 --memory 1024 --vcpus 1 \
  --location ~/debian-12-amd64-netinst.iso --os-variant debian12 \
  --disk path=/var/lib/libvirt/images/vm02.qcow2,size=10,format=qcow2,bus=virtio \
  --network bridge=br0,model=virtio --autostart --graphics none \
  --console pty,target_type=serial \
  --extra-args "console=ttyS0,115200n8 locale=en_US auto=true priority=critical netcfg/use_autoconfig=true netcfg/get_hostname=vm02 preseed/url=http://192.0.2.50:8000/preseed.cfg"

Install interactively with no local GUI

There is no way to answer an installer without some kind of display unless you use an unattended installation. Options:

  • --graphics none with a serial console (as above) works for installers that support text mode.
  • Otherwise forward X11 from a workstation (ssh -X host) and use virt-viewer vm01, or connect with virt-manager.
  • virsh domdisplay vm01 shows the VNC/SPICE address if you would rather use a local viewer.

Import an existing disk image

sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/vm03.qcow2     # qemu:qemu on RHEL-family hosts
sudo virt-install --name vm03 --memory 2048 --vcpus 2 --os-variant ubuntu22.04 \
  --disk path=/var/lib/libvirt/images/vm03.qcow2,device=disk,bus=virtio \
  --network bridge=br0,model=virtio --import --noautoconsole
virsh console vm03

Build a VM from a template (virt-builder)

virt-builder --list
virt-builder fedora-40 -o /var/lib/libvirt/images/vm04.qcow2 --format qcow2 --size 20G \
  --root-password file:./rootpw --ssh-inject root:file:$HOME/.ssh/id_ed25519.pub
sudo virt-install --name vm04 --memory 2048 --vcpus 2 --os-variant fedora40 \
  --disk /var/lib/libvirt/images/vm04.qcow2 --import --noautoconsole

Get the IP of an installing VM

See Find a VM's IP address. During a kickstart install, watch -n 1 'virsh net-dhcp-leases default' or arp -an (compare before and after) will show the new lease.