Virtualization with QEMU, KVM, and libvirt
Fedora Linux comes with native support for virtualization extensions. This support is provided by Kernel-based Virtual Machine (KVM) and is available as a kernel module. QEMU/KVM in combination with the Libvirt management toolkit is the standard virtualization method in Fedora Linux.
Quick Emulator (QEMU) is a full system emulator that works together with KVM and allows you to create virtual machines with hardware and peripherals.
Finally, libvirt
is the API layer and allows you to manage the infrastructure – that is, create and run virtual machines. It includes a local virtual network that enables secure communication between virtual guest systems with each other and with the host. libvirt’s default configuration also allows NAT access to the public network, which is useful for virtual machines or containers that don’t have direct access to the public interface.
The following figure illustrates the QEMU/KVM architecture with libvirt
:

Figure 13.1 – The QEMU/KVM architecture
Let’s take a brief look at the management tools.
Management tools
libvirt
is a C toolkit that interacts with the virtualization capabilities of Fedora Linux. The main package includes the libvirtd
server for exporting virtualization support.
The basic management tools are as follows:
virsh
: This is the main interface for managingvirsh
guest domains. The program can create, pause, and shutdown domains. It also lists the current domains and their status.Virt-manager
: This is a desktop tool for managing virtual machines. It provides life cycle control of current virtual machines (startup/shutdown, pause/resume, and suspend/restore), provisions new virtual machines and various types of storage, manages virtual networks, gives access to the graphical console of virtual machines, and generates performance statistics locally or remotely:

Figure 13.2 – Virtual Machine Manager
virt-viewer
: This is a minimal tool for displaying the graphical console of a virtual machine. It accesses the console using theVNC
orSPICE
protocol. Refer to the virtual guest based on its name, ID, or UUID. If the guest is not running yet, the viewer could wait until it starts before attempting to connect to the console. The viewer could connect to remote hosts to look up console information, as well as connect to the remote console using the same network transport.virt-install
: This is a command-line tool for creating new KVM, Xen, or Linux container guests using thelibvirt
hypervisor management library. Thevirt-install
tool supports graphical installations that useVNC
orSPICE
protocols, as well as text mode installations via serial console. The guest could be configured to use one or more virtual disks, network interfaces, audio devices, and physical USB or PCI devices, among others.The installation media could include local ISOs or CDROMs, or a distribution installation tree hosted remotely via HTTP, FTP, or in a local directory. In the case of the installation tree,
virt-install
obtains the minimum files necessary to start the installation process, allowing the guest to get the rest of the operating system distribution as needed. PXE booting and importing an existing disk image (thus skipping the installation phase) are also supported.With the proper command-line arguments,
virt-install
can run completely unattended, with the guest “booting” itself. This allows for easy automation of the guest installation.
Using virt-install
capabilities enables you to streamline the process of creating virtual machines, minimizing the installation time. Let’s learn how to perform this procedure.
Streamlining the creation of virtual machines
QEMU uses the qcow
file format for disk image files. It stands for QEMU Copy On Write. The qcow
format uses a disk storage optimization strategy that delays the allocation of storage until it is needed. Files within the qcow
format could contain a variety of disk images that are generally associated with specific guest operating systems. There are three versions of the format: qcow
, qcow2
, and qcow3
.
At the time of writing, the vast majority of distributions, including Fedora Linux, offer a cloud-ready downloadable version. One of the available options is the qcow2
image disk format.
OpenStack, an open standard cloud computing platform, provides a web page that references cloud images for many distributions and operating systems (which you’ll find in the next example).
Using the virt-customize
command-line tool, you can modify the downloadable disk image to import it as a ready-to-use virtual machine.
Follow these steps to create a virtual machine in a short time with these three tools:
- Before starting, verify that your workstation runs virtualization-enabled from the BIOS/UEFI.
Note
This process depends on the manufacturer of your workstation. Please refer to the manufacturer’s documentation to confirm that they have virtualization capability enabled in the BIOS/UEFI.
- Confirm that the processor of your workstation has the flags that support virtualization:
$ sudo grep -E 'svm|vmx' /proc/cpuinfo
- Use the
sudo
command to install the packages required for virtualization:qemu-kvm
virt-manager
virt-viewer
guestfs-tools
virt-install
genisoimage
:$ sudo dnf install qemu-kvm virt-manager virt-viewer guestfs-tools virt-install genisoimage
- Use your browser to navigate to https://docs.openstack.org/image-guide/obtain-images.html and download the
qcow2
disk image of the chosen distribution/operating system:

Figure 13.3 – OpenStack – Get images
- For this example, download the Fedora Linux image. Use your browser to navigate to https://fedoraproject.org/cloud/download/:

Figure 13.4 – The Fedora Cloud download page
Download the qcow2
image for x86_64
architectures.
Note
Each image requires about 400 MB of disk space. Ensure that you have enough storage space to store them and let them grow as they get used.
- Move the downloaded
qcow2
image to the KVM working directory in/var/lib/libvirt/images
:$ sudo mv Fedora-Cloud-Base-38-1.6.x86_64.qcow2 /var/lib/libvirt/images/
Note
A best practice is to copy the qcow2
image with the virtual machine name instead of moving it. Reuse the original downloaded image to create many virtual machines:
$ sudo cp
Fedora-Cloud-Base-38-1.6.x86_64.qcow2 /var/lib/
libvirt/images/vmtest01.qcow2
- Use the
virt-customize
command to modify the downloaded image:$ sudo virt-customize \ -a /var/lib/libvirt/images/vmtest01.qcow2 \ --hostname vmtest01.packt.lab \ --root-password password:rootpw \ --ssh-inject 'root:file:labkey.pub' \ --uninstall cloud-init \ --selinux-relabel
Let’s look at each of the options that we used in detail:
virt-customize
modifies the guest or disk image in place. The guest must power off to modify the disk image. There’s no need to runvirt-customize
asroot
user. In this case, use thesudo
command since there are no access rights to the path where this image resides.-a
indicates the path of the disk to customize.--hostname
sets the virtual machine hostname.--root-password
sets the newroot
password, which in this case isrootpw
.--ssh-inject
allows you to inject an SSH key to some user. In this case, this islabkey
for theroot
user.
To generate the SSH key, use the
ssh-keygen
command:$ ssh-keygen -t ecdsa -b 521 -f labkey
Note
For more information on the ssh-keygen
command, refer to the command manual: man ssh-keygen
.
--uninstall
allows us to uninstall the software contained by default in the downloaded image.
cloud-init is a suite that helps initialize an image for use in OpenStack. In this case, it is not necessary since a basic functional level of customization works best here.
Note
If the cloud-init
package is not uninstalled, the VM will take a long time to boot as it waits for the parameters for initialization with cloud-init scripts
.
- Since it is a Fedora Linux image, the SELinux contexts must relabel with the
--selinux-relabel
option as several files must be changed or removed:

Figure 13.5 – Customizing the qcow2 image
Now that we’ve finished customizing, let’s import the disk image as a new virtual machine.
- To import the disk image as a new virtual machine, use the
virt-install
command:$ sudo virt-install \ --name vmtest01 \ --memory 1024 \ --vcpus 1 \ --disk /var/lib/libvirt/images/vmtest01.qcow2 \ --import \ --osinfo fedora38 \ --noautoconsole
Let’s look at each of the options we used in detail:
virt-install
is the command-line tool for creating new VMs.--name
sets the name of the new guest VM instance. The name must remain unique among all guests known to the hypervisor on the connection, including those not currently active.--memory
indicates the memory to allocate for the guest in MiB.--vcpus
indicates the number ofvcpus
to configure for the guest.–disk
specifies the device to use as storage for the guest. In this case, this is the path to the disk image.--import
indicates that the disk image gets imported as a new VM building a guest around this disk image.--osinfo
optimizes the guest configuration for a specific operating system version or distribution. In this case,fedora38
is indicated.
Note
To find the list of supported operating system name values, use the virt-install
command – that is, virt-install --
osinfo list
.
--noautoconsole
specifies not to try to connect to the guest console automatically:

Figure 13.6 – Creating a new virtual machine
- Verify the status of the created virtual machine:
$ sudo virsh list
Here’s the output:

Figure 13.7 – Verifying the new virtual machine’s status
Now, let’s connect to the virtual machine via SSH.
- Use the
virsh
command to find the IP address that was assigned by the virtualization DHCP service:$ sudo virsh domifaddr vmtest01
Here’s the output:

Figure 13.8 – Finding the VM’s IP address
- Use the
ssh
command and the SSH key to access the virtual machine:$ ssh –i labkey root@192.168.124.225
You will get the following output:

Figure 13.9 – Accessing the VM
With that, you can get a working virtual machine up and running in a short time. Mastering these commands speeds up this task.
Before moving on to containerization, which is virtualization in miniature form, let’s look at the tool that GNOME includes as part of its desktop suite.