Virtualization using KVM + QEMU + libvirt

Last updated on 2021-07-09 Tagged under  # virtualization  # debian  # linux

Setup a stack of virtualization tools on a Linux host (Debian) for creating and managing virtual machines (VMs).

Let's go!

KVM (Kernel-based Virtual Machine) is built into the Linux kernel and handles the CPU and memory details. QEMU (Quick EMUlator) emulates the various hardware components of a physical machine. Finally, libvirt provides the tools for creating and managing VMs. I use virt-manager and virsh as graphical and console interfaces respectively.

First, check whether the host computer's CPU supports virtualization ...

$ egrep -c '(vmx|svm)' /proc/cpuinfo

A result of 1 or more means the CPU supports virtualization extensions. A result of 0 means it does not, though double-check the BIOS and see if the extensions are available and just need to be enabled.


Install packages and add username (replace daniel with your own) to the kvm and libvirt groups ...

$ sudo apt install qemu-kvm libvirt-clients libvirt-daemon libvirt-daemon-system virtinst virt-manager bridge-utils
$ sudo usermod -aG kvm daniel
$ sudo usermod -aG libvirt daniel

Log out and back in.

Default directory to hold VM images is /var/lib/libvirt/images. Since I have root and home on separate partitions, and I have much more storage space in home, I create an images directory there, plus an isos directory to hold Linux install images, and create symbolic links to them in /var/lib/libvirt ...

$ mkdir /home/daniel/{images,isos}
$ chown :kvm /home/daniel/images
$ sudo rmdir /var/lib/libvirt/images
$ sudo ln -s /home/daniel/images /var/lib/libvirt/images
$ sudo ln -s /home/daniel/isos /var/lib/libvirt/isos


Permissions can be a wee tricky to get right. In this setup, I run and log into all my VMs on my own laptop, want the VM to run as root, and have all client utilities default to using qemu:///system.

Create ~/.config/libvirt/libvirt.conf ...

$ mkdir ~/.config/libvirt
$ sudo cp -rv /etc/libvirt/libvirt.conf ~/.config/libvirt/
$ sudo chown daniel: ~/.config/libvirt/libvirt.conf

Open the file and set ...

uri_default = "qemu:///system"

For storage file permissions, open /etc/libvirt/qemu.conf and set the user and group ...

user = "root"
group = "kvm"

Create VM

On Debian, libvirtd is enabled and starts upon install ...

$ systemctl status libvirtd

Create a VM using virt-manager. Click the + icon to add a new VM, and work through the series of dialog boxes to configure.

Here I've created two: bullseye and mint ...


Note during the creation of a VM, the network selection option defaults to Virtual network 'default': NAT. If the default network is not active, virt-manager will prompt to start it. Otherwise, start manually with ...

$ virsh net-start default

Each VM (in default) will be a member of the network, with an IP address in the range of to, and are accessible via SSH from the host.

Resize a VM guest window

In the virt-manager console window, navigate to Edit->Preferences->Console and set:

Inside the VM, install a spice agent ...

$ sudo apt install spice-vdagent

Reboot the VM.

In the VM guest window, navigate to View->Scale display and check Always and Auto resize VM with window.

Now click-and-drag the window edge to resize display, or use xrandr to set display size.

virsh and virt-clone

A few commands ...

$ virsh list --all      # list of VMs
$ virsh net-list        # get name of networks
$ virsh net-start <network_name>        # startup an inactive network
$ virsh net-dhcp-leases <network_name>  # show IP addresses
$ virt-clone --original <vm_name> --name <new_vm_name> \
--file /var/lib/libvirt/images/<new_vm_name>.qcow2  # clone VM <vm_name> to <new_vm_name> and create storage image <new_vm_name>.qcow2


« Earlier: Getting started with Git and GitLab