Nemanja Tomic
Sep 13, 2025 • 7 min read
Virtualization is a great technology for everyone working in IT. Whenever you want to try out something new or test out a blueprint for your infrastructure, virtualization will help you tremendously in terms of time efficiency. And if you break something, it isn't half as bad as if you did on your bare metal machine since you can easily just spin up a new VM (virtual machine) in a matter of seconds. And I promise, once you have set up a system for managing your VMs, the rest is a piece of cake.
In this tutorial, we will go through the process of setting up a system that can create, manage and use virtual machines. We will use Arch Linux on our host OS, but it works on basically any other Linux distribution aswell (I tested it on Ubuntu and Fedora).
For our hypervisor, we will use KVM (Kernel-based Virtual Machine), mainly because it has been the most popular hypervisor for Linux for over 10 years now, and there is no real reason to use another one than KVM. And because we don't want to read the 1000 pages long documentation of KVM, we will also use libvirt on top of KVM.
Libvirt is an abstraction layer that gives us a few handy tools for creating and managing our VMs. The great thing about libvirt is that it brings the complexity of KVM to a human understandable level, making our lives that much easier. With libvirt, we also get access to several GUI and CLI tools like virt-manager or virt-clone, that allow us to do virtually anything we want with your VMs.
Before we begin, we need to make sure some dependencies are installed on the system. The tools are as follows.
Key system tools: These are the key tools/services/features that enable virtualization:
User/client tools: These tools can be interacted with by users / services.
Ancillary system tools: These tools are used to support the system tools listed above.
To install all the packages and dependencies listed above, run this command:
pacman -Sy --needed \
qemu \
dhclient \
openbsd-netcat \
virt-viewer \
libvirt \
dnsmasq \
dmidecode \
ebtables \
virt-install \
virt-manager \
bridge-utils
Now I know I just said that the process is the same for all Linux distributions, but this step might be a bit different because the names for the packages might not be exactly the same. So if you are not using Arch at the moment, I advise you to ask AI what the corresponding package names for your distribution are to get a quick and easy answer. We won't need to install KVM because it comes preinstalled with the Kernel.
The next thing we have to do is to enable the libvirtd service. Suppose your system uses systemd for managing system processes (most modern systems do), we can enable and start the libvirtd service with the following command.
sudo systemctl enable --now libvirtd
Now libvirtd is alive and can talk to the backend systems, which means our tools that we're going to use are now working.
Libvirt keels its files at /var/lib/libvirt
. There are multiple directories within.
drwx--x--x. 1 root root 0 Jun 20 02:00 boot/
drwxr-xr-x. 1 root root 118 Sep 13 12:12 dnsmasq/
drwx--x--x. 1 root root 0 Jun 20 02:00 filesystems/
drwx--x--x. 1 root root 0 Jun 20 02:00 images/
drwx------. 1 root root 30 Sep 13 10:58 libxl/
drwx------. 1 root root 0 Jun 20 02:00 lxc/
drwx------. 1 root root 0 Jun 20 02:00 network/
drwxr-x--x. 1 qemu qemu 68 Jun 20 02:00 qemu/
drwx--x--x. 1 root root 0 Jun 20 02:00 swtpm/
The images
directory is the default location a VM's disk image will be stored (e.g. (qcow2)[https://en.wikipedia.org/wiki/Qcow]).
The primary tricky bit is getting permissions correct. There are a few key pieces to configure so your using can interact with qemu:///system
. This enables VMs to run as root, which is generally what you'll want. This is also the default used by virt-manager. (Check out this blog post form Colin Robinson, which calls out the differences)[https://blog.wikichoon.com/2016/01/qemusystem-vs-qemusession.html].
virsh
will use qemu://session
by default, which means CLI calls not run as sudo
will be looking at a different user. To ensure all client utilities default to qemu:///system
, add the following configuration to your .config
directory.
sudo cp -rv /etc/libvirt/libvirt.conf ~/.config/libvirt/
sudo chown ${YOURUSER}:${YOURGROUP} ~/.config/libvirt/libvirt.conf
Don't forget to uncomment the last line in the file after you copied it to your local configurations. Otherwise, your virsh will still use the user context instead of the system context.
Depending on the option you go with, you may need to re-login or at least restart libvirtd (see below).
Pro tip
When using qemu:///system, access is dictated by polkit. If you don't want to enter your password everytime you start virt-manager, create a file at /etc/polkit-1/rules.d/50-libvirt.rules
and paste the following in.
edit /etc/polkit-1/rules.d/50-libvirt.rules
/* Allow users in wheel group to manage the libvirt
daemon without authentication */
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.unix.manage" &&
subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
This adds your group to the polkit config. You will not be prompted for a password when interacting with virt-manager or virsh.
And that should be it. If you run virt-manager
in your terminal, a GUI will pop up and you can setup your VM with the ISO of your choice. The rest is pretty self-explanetory, so I won't go into more detail. If you want to know the various tools that you can use with libvirt, checkout (this page)[https://libvirt.org/apps.html] where all the possible tools are listed. I'm sure you'll find something that is appropriate for your use case.
Enter your email to receive the latest articles about tech, work and life.