Install KVM, QEMU and Libvirt on Arch Linux

Let’s start with some definitions and/or reminders for some folks.

KVM, Kernel-based Virtual Machine, is a (type 1 or bare-metal) hypervisor built into the GNU/Linux kernel.

QEMU, Quick EMUlator, is a generic and open source machine emulator and virtualizer.

Libvirt is a collection of software that provides a convenient way to manage virtual machines and other virtualization functionality, such as storage and network interface management.

The KVM module

Inside the GNU/Linux kernel, KVM acts as a module. This is the component in charge of managing the hardware virtualization management functions as well as the interactions with the hypervisor components of the Linux kernel which it does not manage (such as the scheduling of virtual machines). Depending on the hardware architecture, it may be the only software component to run with access rights to the hardware virtualization APIs (this is the case on ARM for example).

QEMU’s role

Qemu is an emulator. Its purpose is to emulate a number of functions that the KVM module is not able to handle by itself:

QEMU handles startup/shutdown sequences and I/O when these do not correspond to direct access to a physical or hardware virtualizable device. Although the presence of the QEMU process on top of the host kernel gives the impression that the virtual machine kernel is running in an application context, this is not true. QEMU can be seen as an element to be placed as an emulation function of some I/O placed next to the actual context of the virtual machine. It behaves then as an I/O proxy function for the guest OS.

It is important to understand that QEMU is not strictly interconnected to KVM. The KVM module provides an API that allows any application solution able to emulate the startup of a physical machine and to proxify I/O to take the place of QEMU.

Libvirt’s role

Libvirt brings the administration, control and local management of the hypervisor. It allows to manage the creation, the moving, the destruction and more generally the life cycle of the virtual machines. It is not specific to KVM and is not involved in the actual execution of the virtual machine.

What about security?

It is not the subject of this article, but the presence of several virtual machines on the same physical machine implies a large number of impacts in terms of security. Furthermore, it is important to:

Virtual machines, in order to interact with the software environment that carries them, rely on the QEMU process. The latter must therefore be restricted to limit the risk of virtual machine evasion (capacity, for a virtualized software function, to leave its virtualized context). Libvirt thus brings elements for security by simplifying the segregation of the virtual machines via a SELinux driver and via cgroups. The goal is to limit the access of the QEMU process, in charge of managing the I/O of the virtual machine.

Information and requirements

These elements are to be taken into consideration to follow this article:

Update the system

yay -Syyuu --noconfirm

Install required packages

Some additional information about the packages:

Heavy version

The following packages install everything needed to use KVM but also a GUI to manage virtual machines, network…

yay -S dnsmasq qemu virt-manager iptables-nft dmidecode libvirt virt-install

Light version

The following packages install everything needed to use KVM but without the GUI, that’s what I’ll install.

yay -S dnsmasq qemu-headless iptables-nft dmidecode libvirt virt-install

Initial steps

If you want to play with Libvirt, you must be in the libvirt group.

sudo usermod -aG libvirt $USER

At this point, if you are using fish shell like me, you need to log out and log back in. The newgrp command doesn’t seem to work properly with fish shell.

Once logged back in, you can start the different services.

sudo systemctl enable --now libvirtd
sudo systemctl enable --now dnsmasq.service

You can of course make sure that Libvirt daemon runs by checking its status.

udo systemctl status libvirtd
● libvirtd.service - Virtualization daemon
     Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: disabled)
     Active: active (running) since Wed 2021-04-28 23:58:59 CEST; 1s ago
TriggeredBy: ● libvirtd.socket
             ● libvirtd-admin.socket
             ● libvirtd-ro.socket
       Docs: man:libvirtd(8)
             https://libvirt.org
   Main PID: 32610 (libvirtd)
      Tasks: 19 (limit: 32768)
     Memory: 6.0M
        CPU: 124ms
     CGroup: /system.slice/libvirtd.service
             └─32610 /usr/bin/libvirtd --timeout 120

Apr 28 23:58:59 lap-001-1 systemd[1]: Started Virtualization daemon.

You must also set your default text editor to edit configuration file.

echo "EDITOR=vim" | sudo tee -a /etc/environment

Test if Libvirt is working properly on a system level.

virsh --connect qemu:///system
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh #

Test if Libvirt is working properly for a user-session.

virsh --connect qemu:///session
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh #

Later we will install a virtual machine in text mode. To do this, we will connect to the machine’s serial port. It is required to start and activate the ttyS0 service.

sudo systemctl enable --now serial-getty@ttyS0.service

Management and environment

Libvirt management is done mostly with three tools: virt-manager (the GUI), virsh, and guestfish. Since I don’t have a GUI installed and I love the command line, I will only use virsh.

virsh

The virsh program manages virtual machines. Though most virsh commands require root privileges to run due to the communication channels used to talk to the hypervisor, typical management, creation, and running of VMs (as it is done with VirtualBox) can be done as a regular user. Also, virsh includes an interactive terminal that can be entered if no commands are passed. The interactive terminal has support for tab completion.

From the command line

virsh [option] <command> [argument]...

From the interactive terminal

virsh # <command> [argument]...

Help

If you have already used Docker, this will be familiar to you. To get help on a command, the keyword help must be prefixed. For example, to get help with the create command, you’d write this.

virsh help create
  NAME
    create - create a domain from an XML file

  SYNOPSIS
    create <file> [--console] [--paused] [--autodestroy] [--pass-fds <string>] [--validate]

  DESCRIPTION
    Create a domain.

  OPTIONS
    [--file] <string>  file containing an XML domain description
    --console        attach to console after creation
    --paused         leave the guest paused after creation
    --autodestroy    automatically destroy the guest when virsh disconnects
    --pass-fds <string>  pass file descriptors N,M,... to the guest
    --validate       validate the XML against the schema

Now, enter the following command to view the list of available commands along with brief description. You’ll see an extensive list of available virsh commands to manage KVM virtual machines from command line.

virsh help
Grouped commands:

 Domain Management (help keyword 'domain'):
    attach-device                  attach device from an XML file
    attach-disk                    attach disk device
[...]

The commands are grouped into the following sections:

Each section contains the commands related to do particular set of tasks. You can view help section of a group, for example Storage Volume, like this.

virsh help volume
 Storage Volume (help keyword 'volume'):
    vol-clone                      clone a volume.
    vol-create-as                  create a volume from a set of args
    vol-create                     create a vol from an XML file
    vol-create-from                create a vol, using another volume as input
    vol-delete                     delete a vol
    vol-download                   download volume contents to a file
    vol-dumpxml                    vol information in XML
    vol-info                       storage vol information
    vol-key                        returns the volume key for a given volume name or path
    vol-list                       list vols
    vol-name                       returns the volume name for a given volume key or path
    vol-path                       returns the volume path for a given volume name or key
    vol-pool                       returns the storage pool for a given volume key or path
    vol-resize                     resize a vol
    vol-upload                     upload file contents to a volume
    vol-wipe                       wipe a vol

With this help, no one will tell you RTFM anymore.

Storage pools

A pool is a location where storage volumes can be kept. What Libvirt defines as volumes others may define as “virtual disks” or “virtual machine images”. Pool locations may be a directory, a network filesystem, or partition (this includes a LVM). Pools can be toggled active or inactive and allocated for space. Learn more here.

On the system-level, /var/lib/libvirt/images/ will be activated by default and that’s what we’ll use.

Domains

Virtual machines are called domains. If working from the command line, use virsh to list, create, pause, shutdown domains, pools, volumes…

Command to print active and inactive domains.

virsh list --all
 Id   Name   State
--------------------

We have seen many things in this article and the purpose of this one was to install the necessary tools to use KVM. It’s done. In the next article, we will see how to create a virtual machine, how to perform basic operations with virsh, how to create a template to save time and more.