Skip to content

create and run VM in KVM

Generally qcow images which are OS preinstalled hard drive images are the most easiest way to spin up virtual machines in KVM or any other virtualization platforms. They can be easily customized using cloud-init

download debian 12 qcow image

wget -c https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2
sudo mv debian-12-generic-amd64.qcow2 /var/lib/libvirt/images/
OS images for KVM are stored in /var/lib/libvirt/images/ location.

create a linked clone of the image

linked clones consume less space. However the base image debian-12-generic-amd64.qcow2 should not be modified. It will have unwanted issues on the cloned disks.

sudo qemu-img create -f qcow2 -b /var/lib/libvirt/images/debian-12-generic-amd64.qcow2 -F qcow2 /var/lib/libvirt/images/server.qcow2 40G

create a routed network

It can be created using an xml file named network.xml. Once the vm-routed.xml file has been created.

<network>
  <name>vm-routed</name>
  <forward mode="route"/>
  <bridge name="virbr1"/>
  <ip address="192.168.200.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.200.10" end="192.168.200.100"/>
    </dhcp>
  </ip>
</network>
virsh commands can be used to create the network.
virsh net-define network.xml
virsh commands can be used to list all active networks
virsh net-list

create a virtual machine

virt-install --name server\
    --ram 1024 --vcpus 1\
    --disk path=/var/lib/libvirt/images/server.qcow2,format=qcow2,bus=virtio \
    --disk path=/var/lib/libvirt/images/server.seed.iso,format=raw,bus=virtio,readonly=on \
    --os-variant debian12 \
    --network network=vm-routed,model=virtio \
    --noautoconsole \
    --import \
    --noautoconsole \
    --nographics

connect to the virtual machine

virsh console server

enable vnc on the virtual machine

sudo virt-install \
  --name winserver \
  --os-variant win2k22 \
  --virt-type kvm \
  --machine q35 \
  --cpu host \
  --vcpus 4 \
  --memory 8192 \
  --disk path=/var/lib/libvirt/images/winserver.qcow2,format=qcow2,bus=virtio,size=100 \
  --cdrom /path/to/Windows_Server_2022.iso \
  --disk path=/var/lib/libvirt/iso/virtio-win.iso,device=cdrom \
  --network network=vm-routed,model=virtio \
  --graphics vnc,listen=0.0.0.0,port=5900
  --boot uefi \
  --noautoconsole

list all virtual machines

sudo virsh list --all

accessing vnc console from mac

screen sharing app can be used to access VNC console. By default it requires passowrd. Since the password has not been set earlier. It can be set editing the virtual machine xml file using the command.

sudo virsh edit winserver
On the graphics section update the password for the vnc connection
<graphics type='vnc' port='5900' autoport='no' listen='127.0.0.1' keymap='en-us' passwd='nepal'>
    <listen type='address' address='127.0.0.1'/>
</graphics>

adding cdrom to the boot order

The boot device for the virtual machine might casue some issues. Setting boot order in virtual machine in os section

<os>
    <type arch='x86_64' machine='pc-q35-6.2'>hvm</type>
    <boot dev='hd'/>
    <boot dev='cdrom'/>
    <boot dev='network'/>
</os>

sending ctrl+alt+delete keys

ctrl+alt+delete keys needs to be passed to virtual machine for login. Apparently it doesn't work with vnc app. At least didn't work for the screen sharing app in mac. keys can be sent to the vm from virsh command using

sudo virsh send-key winserver KEY_LEFTCTRL KEY_LEFTALT KEY_DELETE
It will send ctrl+alt+del keys on the winserver virtual machine. It lets the virtual machine to pass the login screen and move ahead with the username password screen.