Performance-Oriented Virtualization with QEMU, KVM, and SPICE: A Practical Guide

Performance-Oriented Virtualization with QEMU, KVM, and SPICE: A Practical Guide

Introduction

This tutorial is about QEMU, KVM, and SPICE to understand how these tools work and how they can be leveraged for virtualization tasks on a Linux system. We will see how these tools work together to provide a robust virtualization solution:

  • QEMU emulates the hardware
  • KVM allows the guest OS to run on the physical hardware through the host kernel
  • SPICE enables a high-quality remote view of the guest OS and additional features that enhance the user experience

We will also compare the performance of the host machine and the VM using sysbench, geekbench, and the results will show comparable performance between them.

Furthermore, we will discuss the setting up of a network bridge on Ubuntu, which enables the virtual machines to communicate with other devices on the network. A step-by-step guide, starting from installing the necessary packages to making the bridge configuration permanent.

Lastly, we will walk through the process of setting up a VM using QEMU, KVM, and SPICE, and managing VMs using virsh and virt-viewer.

Understanding Virtualization

While virtualization is a commonly understood concept, achieving an efficient and seamless virtualization experience requires a deeper understanding of the tools at hand. Let’s delve into QEMU, KVM, and SPICE, and see how they work together to provide a robust virtualization solution.

QEMU (Quick Emulator) is a free and open-source machine emulator and virtualizer that can perform hardware virtualization. As an emulator, it can replicate various hardware devices, allowing a guest operating system to interact with these devices as if they were real. As a virtualizer, QEMU leverages the hardware virtualization capabilities of modern CPUs to run guest OSes at near-native speeds.

KVM (Kernel-based Virtual Machine), on the other hand, is a module integrated into the Linux kernel that turns Linux into a hypervisor. A hypervisor is a layer of software which enables multiple operating systems to share the same hardware simultaneously. KVM works closely with QEMU to run multiple, unmodified guest operating systems efficiently with the help of hardware virtualization extensions.

SPICE (Simple Protocol for Independent Computing Environments) is a remote display protocol designed for virtual environments. It allows users to view a computing “desktop” environment — not only on its computer server, but also from anywhere on the Internet — and from a wide variety of machine architectures. When used with QEMU and KVM, SPICE provides a high-quality remote viewing experience and enables some useful features, such as audio and file sharing between host and guest.

By combining QEMU’s hardware emulation, KVM’s hypervisor capabilities, and SPICE’s features for remote access, you can have a virtualization experience that rivals native installations in performance and usability.

Benchmarks

Machine Metric Score
Host Geekbench Single Core 2062
QEMU+KVM Geekbench Single Core 2031
Host Sysbench - events per second 10429.33
QEMU+KVM Sysbench - events per second 10537.44

Setting Up a Network Bridge on Ubuntu

A network bridge is a Link Layer device which forwards traffic between networks based on MAC addresses. It’s primarily used in scenarios where you want to make your virtual machines accessible from other machines in the network.

Step 1: Install the Necessary Packages

First, you will need the bridge-utils package. This provides a collection of utilities for managing network bridges. Install it with the following command:

sudo apt update
sudo apt install bridge-utils

Step 2: Identify Your Network Interfaces

Next, you need to know the name of your network interfaces. Use the following command to list them: ip link show

This will display a list of network interfaces. You should see your primary network interface, which is typically named eth0 or enp2s0 or similar, and any other network interfaces.

Step 3: Create a New Network Bridge

To create a new network bridge named br0, use the following command: sudo ip link add name br0 type bridge

Step 4: Connect Your Network Interface to the Bridge

Now, you can connect your physical network interface to the bridge. Replace enp2s0 with the name of your network interface: sudo ip link set enp2s0 master br0

Step 5: Enable the Bridge and the Network Interface

After connecting the interface to the bridge, enable the bridge and the network interface with the following commands:

sudo ip link set dev br0 up
sudo ip link set dev enp2s0 up

Step 6: Configure Network Settings for the Bridge

Lastly, you’ll need to configure the bridge to use the same IP address and network settings as your physical interface. If you’re using DHCP, you can use the dhclient command: sudo dhclient br0

Step 7: Make the Bridge Configuration Permanent

The changes made with the ip command are not persistent across reboots. Write your configuration in a YAML file under /etc/netplan:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp5s0:
      dhcp4: no
  bridges:
    br0:
      interfaces: [enp5s0]
      dhcp4: yes

Then, restart your network or reboot your system to apply the changes: sudo netplan apply

And that’s it! You have set up a network bridge on Ubuntu. You can now use this bridge when creating virtual machines, allowing them to communicate with other devices on your network.

Setting up VM using QEMU, KVM and SPICE

Before starting, please ensure that your CPU supports hardware virtualization. You can do this by running the following command: egrep -c '(vmx|svm)' /proc/cpuinfo

If the output is 0, your CPU doesn’t support hardware virtualization, and you won’t be able to use KVM. If the output is 1 or more, you can proceed with the following steps.

Step 1: Install KVM and QEMU

For Debian-based distributions like Ubuntu, use the following command:

sudo apt-get update
sudo apt-get install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager

Step 2: Check if the KVM module is loaded

You can check this by running the following command: lsmod | grep kvm

Step 3: Add your user to the libvirt group

You’ll need to add your user to the libvirt group to manage VMs, command: sudo adduser $USER libvirt

* You may need to log out and log back in for this change to take effect.

Step 4: Download Ubuntu 20.04 ISO

You can download the ISO from the official Ubuntu website or with command: wget https://releases.ubuntu.com/focal/ubuntu-20.04.6-desktop-amd64.iso

Step 5: Create a new disk image

This will be the virtual hard drive for your VM. You can create it with the following command (don’t worry about the size, image won’t consume disk space until it actually requires it): qemu-img create -f qcow2 ubuntu20.qcow2 100G

Step 6: Install the VM

You can start the VM and boot from the ISO with the following command:

virt-install --name ubuntu20 --ram 4096 --disk path=ubuntu20.qcow2 --vcpus 2 --os-variant ubuntu20.04 --network bridge=br0 --graphics spice --video qxl --channel spicevmc --cdrom '/home/arturs/Downloads/ubuntu-20.04.6-desktop-amd64.iso'

--ram 4096: This specifies the amount of RAM for the virtual machine in megabytes. In this case, the VM will have 4096 MB (or 4 GB) of RAM.

--disk path=ubuntu20.qcow2: This is the path to the disk image file that the VM will use for storage.

--vcpus 2: This sets the number of virtual CPUs to 2. Note that the host machine needs to have at least this many physical cores.

--os-variant ubuntu20.04: As we know that we're installing Ubuntu 20.04, we can set the OS variant accordingly. This helps virt-install optimize the VM's settings for this OS.

--network bridge=br0: This sets up a network bridge so that your VM can connect to your network. br0 is the name of the bridge on the host system.

--graphics spice enables the SPICE server.

--video qxl sets the video model to QXL, which is optimized for the SPICE protocol.

--channel spicevmc adds a virtual hardware channel to the guest for the SPICE agent. This allows for features like clipboard sharing and dynamic screen resizing.

--cdrom 'ubuntu-20.04.6-live-server-amd64.iso': This is the location of the installation media. In this case, it's pointing to an Ubuntu 20.04 ISO file.

Step 7: Install Agent on VM

Once ubuntu installation finished, you must install guest agents for best performance.

sudo apt update
sudo apt upgrade
sudo apt install qemu-guest-agent spice-vdagent xserver-xorg-video-qxl

Managing and Connecting to VMs using virsh and virt-viewer

Managing VMs with virsh

virsh is a command line tool for managing VMs and hypervisors. It is built on top of the libvirt library and allows you to interact with the virtualization capabilities of recent versions of Linux.

Here’s how to start, stop, reboot and remove a VM with virsh:

Starting a VM:

  1. To start a VM, you’ll need to know its name or ID. You can list all VMs with the virsh list --all command.
  2. Once you have the VM’s name, you can start it with the virsh start command: virsh start <vm-name>

Shutting it down gracefully: virsh shutdown <vm-name>

Rebooting a VM can be done using command: virsh reboot <vm-name>

Removing VM from hypervisor must be done with command: virsh undefine <vm-name>

Connecting to VMs with virt-viewer

virt-viewer is a lightweight UI interface for viewing and interacting with the graphical console of VMs. It can display the desktop of a VM and also redirect the keyboard and mouse events to the VM.

You can use virt-viewer to connect to a VM using the SPICE protocol, which provides a superior user experience, including features like audio and USB redirection.

Here’s how to connect to a VM with virt-viewer:

Install virt-viewer:

First, you’ll need to install virt-viewer if you haven't already. On Ubuntu, you can install it with the following command: sudo apt install virt-viewer

Connect to a VM:

Once virt-viewer is installed, you can connect to a VM with the virt-viewer command:virt-viewer -c qemu:///system --wait <vm-name>

Final Thoughts

Virtualization is a powerful technology that allows for efficient use of hardware resources. QEMU, KVM, and SPICE are robust tools that work together to provide efficient and seamless virtualization experience on a Linux system. Understanding how these tools work and how to use them can greatly enhance your ability to effectively manage and utilize virtual machines.

The sysbench and geekbench outputs confirm that the use of QEMU, KVM can offer near-native performance, which is a testament to the power of modern virtualization technologies.

Finally, the ability to set up and manage virtual machines using the mentioned tools and utilities demonstrates the flexibility and power of Linux for virtualization tasks. This knowledge can be beneficial in various scenarios, from testing and development to running production workloads in isolated environments.