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:
- To start a VM, you’ll need to know its name or ID. You can list all VMs with the
virsh list --all
command. - 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.