How to Install KVM on Linux and Run Guest OS Faster

How to Install KVM on Linux and Run Guest OS Faster Feature Image

The Kernel-based Virtual Machine (KVM) is a full virtualization hypervisor for Linux. When you install KVM on Linux, it transforms your Linux distribution into a type-1 hypervisor (bare-metal), enabling you to operate virtual machines at speeds close to the host machine. In KVM, each virtual machine will have its own private virtualized hardware, such as a network card, disk, graphic card, and so on.

In this blog, you will learn how to install KVM on Linux properly so that you can run your guest operating system a lot faster. So, let’s get started.

1. Overview of key KVM components

Before you can install KVM on Linux, you need to know what are the key components of KVM and what makes it work faster. Here is a quick overview.

1.1 KVM Kernel Modules

At the heart of KVM virtualization are its kernel modules. They consist of a loadable kernel module kvm.ko, which provides the core virtualization infrastructure, and a processor-specific kernel module kvm-intel.ko (Intel) or kvm-amd.ko (AMD).

The kernel modules will use the hardware virtualization capabilities of the CPU (Intel VT-x or AMD-V) to make Linux a type-1 hypervisor. This allows you to run guest operating systems at speeds close to the host machine.

However, because kernel modules lack an interface, they provide all of the resources required to manage virtualization to user-space software.

1.2 QEMU

At the user-space level, it is managed by QEMU (Quick EMUlator). QEMU is a generic and open-source machine emulator and virtualizer. It provides hardware emulation like hard disks, network cards, VGA, PCI, etc., and a low-level interface to the virtual machine.

QEMU alone can emulate an entire machine, including a processor and various devices in the software with no need for hardware-assisted virtualization. As an emulator, QEMU may thus target a broad range of computer architectures, from conventional x86-64 PCs to architectures such as ARM, MIPS, SPARC, and others. For example, on your host PC with x86_64 board, you can run a virtual machine that can emulate Raspberry Pi with raspi3b board. Since this emulation happens entirely through software, It will be accurate but slow.

But when QEMU is paired with KVM, it’s a different story altogether. In the QEMU-KVM setup, QEMU focuses on emulating hardware devices while allowing the hypervisor (KVM kernel modules) to manage the CPU. With hypervisor support, QEMU may reach virtual machine CPU performance as near to that of the host computer.

1.3 Libvirt

Libvirt is a software suite that provides various tools to manage virtual machines and other virtualization functionality. These tools include an open-source API, a daemon (libvirtd), and a command-line utility (virsh).

Some of the key capabilities of libvirt include virtual machine management, remote machine support, network and storage management, as well as virtual NAT and route-based network management.

Libvirt also provides a common means of managing multiple different virtualization platforms. Supported virtualization platforms include QEMU/KVM, Bhyve, Hyper-V, LXC, OpenVZ, PowerVM, UML, VMware ESXi and GSX, VMware Workstation, VirtualBox, and Xen.

1.4 XML Configuration File

Each virtual machine is associated with an XML configuration file (also called Domain XML) which defines all its settings.

When a virtual machine is started, the hypervisor uses this XML configuration file to create an instance of that virtual machine as a regular Linux user-space process on the host. This user-space process is scheduled by the standard Linux scheduler and can be managed by Linux utilities like top and kill.

These domain XML configuration files are located in the /etc/libvirt/qemu/ directory.

Now that you are familiar with the key components of the KVM hypervisor, begin to install KVM on Linux.

2. Make sure your CPU supports hardware virtualization

To install KVM on Linux properly, your processor needs to support hardware virtualization. Depending on the processor type, it will be either Intel’s VT-x or its AMD equivalent, AMD-V.

To find out, run the following command.

$ lscpu | grep Virtualization
Virtualization:          VT-x

I am using an Intel processor. So, I am getting VT-x as output. If you are using an AMD processor, you should get AMD-V as output.

If the output is blank, then the hardware virtualization extension is likely deactivated in the BIOS/UEFI. Enable it before continuing. It will be under the CPU configuration section.

3. Check if your kernel has supplied KVM modules

All the major Linux kernels after version 2.6.20 include KVM modules.

$ find /lib/modules/$(uname -r)/kernel/ -name '*kvm*'
/lib/modules/5.14.9-200.fc34.x86_64/kernel/arch/x86/kvm
/lib/modules/5.14.9-200.fc34.x86_64/kernel/arch/x86/kvm/kvm-amd.ko.xz
/lib/modules/5.14.9-200.fc34.x86_64/kernel/arch/x86/kvm/kvm-intel.ko.xz
/lib/modules/5.14.9-200.fc34.x86_64/kernel/arch/x86/kvm/kvm.ko.xz
/lib/modules/5.14.9-200.fc34.x86_64/kernel/drivers/gpu/drm/i915/gvt/kvmgt.ko.xz
/lib/modules/5.14.9-200.fc34.x86_64/kernel/drivers/ptp/ptp_kvm.ko.xz

The KVM kernel modules should be loaded by default.

$ lsmod | grep kvm
kvm_intel             331776  0
kvm                  1019904  1 kvm_intel
irqbypass              16384  1 kvm

If both steps are successful, continue to install KVM.

4. Install KVM on Linux CLI or GUI

The minimum components you need to run KVM on Linux are 1) KVM kernel modules, 2) QEMU, and 3) Libvirt software suite. As Linux already comes with pre-loaded KVM kernel modules, you just need to install QEMU and Libvirt to run the KVM hypervisor. However, there are a number of additional virtualization management packages available that are recommended when using virtualization.

Fedora Linux

$ sudo dnf install qemu-kvm libvirt virt-install qemu-img \
    guestfs-tools libosinfo

Rocky Linux

$ sudo dnf install qemu-kvm libvirt virt-install qemu-img \
    libguestfs-tools libosinfo

Ubuntu / Debian Linux

$ sudo apt --no-install-recommends install qemu libvirt-daemon-system \
    virtinst qemu-utils libguestfs-tools libosinfo-bin

If you don’t need a GUI to manage your virtual machines, then this is all you need. But if you do, install the following.

Fedora / Rocky Linux

$ sudo dnf install virt-manager virt-viewer

Ubuntu / Debian Linux

$ sudo apt install virt-manager virt-viewer

Virtual Machine Manager

How to Install KVM on Linux and Run Guest OS Faster VMM

A short description of the above packages.

  • qemu-kvm/qemu: A user-level KVM emulator that facilitates communication between hosts and VMs.
  • libvirt/libvirt-daemon-system: A daemon that handles library calls, manages VMs and the hypervisor.
  • virt-install/virtinst: This allows you to create new guest virtual machines.
  • qemu-img/qemu-utils: Provides tools to create, convert, modify, and snapshot offline disk images.
  • guestfs-tools/libguestfs-tools: Provides miscellaneous system administrator command-line tools for virtual machines.
  • libosinfo/libosinfo-bin: A library for managing OS information for virtualization.
  • virt-manager: Graphical tool for managing libvirt virtual machines.
  • virt-viewer: Graphical console for a virtual machine.

5. Enable and review the libvirt service

Start and enable the libvirt service.

$ sudo systemctl enable --now libvirtd.service

Check if your host is set up properly to run all libvirt hypervisor drivers.

$ virt-host-validate

Note: You may receive the following warning message from the validation tool.

QEMU: Checking for device assignment IOMMU support : WARN (No ACPI DMAR table found, IOMMU either disabled in BIOS or not supported by this hardware platform)

Meaning: Your Intel processor only supports VT-x (vmx) feature and does not support VT-d. The VT-d feature allows you to dedicate a PCI device to a guest system that makes it more efficient than emulation.

QEMU: Checking if IOMMU is enabled by kernel : WARN (IOMMU appears to be disabled in kernel. Add intel_iommu=on to kernel cmdline arguments)

Meaning: Your Intel CPU does support the VT-d feature, but must be enabled in the kernel. The solution is to add intel_iommu=on kernel argument to GRUB_CMDLINE_LINUX line in /etc/default/grub file. So, open the /etc/default/grub file and make the following changes. Changes are in bold.

GRUB_CMDLINE_LINUX="... intel_iommu=on"

Then update grub2 conf.

Fedora / Rocky Linux

### For BIOS
# grub2-mkconfig -o /etc/grub2.cfg

### For UEFI
# grub2-mkconfig -o /etc/grub2-efi.cfg

Ubuntu / Debian Linux

$ sudo update-grub

6. Give user system-wide permission

Libvirt provides two ways to connect the local qemu-kvm hypervisor.

  • qemu:///session: To connect locally as a normal user to a per-user instance.
  • qemu:///system: To connect locally as a root user to a system instance.

Per-User instance

By default, if a virtual machine is run as a normal user, it will connect to libvirt using the qemu:///session URI string. This allows users to manage only the virtual machines that belong to that user.

$ virsh uri
qemu:///session

System instance

If you would like to manage the system set of virtual machines, you should run as a root or connect with the qemu:///system URI. To manage system instance virtual machines as a normal user, that user needs to be added to the libvirt group.

When libvirtd runs as root, it gets access to all of the host resources. So it is recommended to use qemu:///system while connecting to the local hypervisor. qemu:///system is also what tools like virt-manager default to.

$ sudo usermod -aG libvirt <username>

Define the environment variable LIBVIRT_DEFAULT_URI in the local .bashrc file of the user.

$ echo "export LIBVIRT_DEFAULT_URI='qemu:///system'" >> ~/.bashrc
$ source ~/.bashrc

Now, by default, you will be able to create and manage virtual machines in system instance.

$ virsh uri
qemu:///system

7. Setup the default virtual network

KVM comes with a default network. This network uses a virtual bridge on the host in combination with NAT to allow a guest to get outbound connectivity.

Ensure that the default network is active.

$ virsh net-list --all
 Name      State      Autostart   Persistent
----------------------------------------------
 default   inactive   no          yes

As you can see in the output above, the default network state is inactive, and autostart is set to no. So let’s activate it.

If the state in your Linux distribution is active and autostart is yes, you may skip this step and go to the next.

$ virsh net-start default

$ virsh net-autostart default

$ virsh net-list --all
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes

By default, the guest OS will get an IP address in the 192.168.122.0/24 address space and the host OS will be reachable at 192.168.122.1.

$ virsh net-dumpxml default
<network>
  <name>default</name>
  <uuid>7e30f1bf-eb4f-4131-baca-2143df731255</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:cd:b4:22'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

Guests within the default network will have all the access to network services, but computers external to the host cannot communicate with the VMs inside the host. The guest, for example, can browse the web, but will not be able to host a web server that is accessible to the outside world.

If this setup is OK for you, no extra configuration is needed, otherwise, configure a network bridge.

8. Configure a network bridge (Optional)

If you want virtual machines to show up on the same network as the host, you must use the network bridge instead.

A network bridge is a link-layer device that connects two local area networks into one network. In this case, a software bridge is used within a Linux host to simulate a hardware bridge. As a result, all other physical machines on the same physical network of the host can detect and access virtual machines. The guest, for example, can browse the web, and will also be able to host a web server that is accessible to the outside world.

Prior to creating a network bridge, you must first find the network interface device on your host.

$ nmcli connection show --active
NAME    UUID                                  TYPE      DEVICE    
enp3s0  d22fb0e8-2a07-3ad4-b67a-2dcd55123456  ethernet  enp3s0    
mdd     91593f85-8945-4889-aaa7-ee0633654321  wifi      wlp0s20u5 
virbr0  dfb64b86-b728-4c52-8188-e7ea98346b54  bridge    virbr0

Make a note of your network interface device. In my case, the device is enp3s0.

Now create a network bridge. I name it br0, but you can name it whatever you like. Based on how your IP address is assigned, choose one of the following two methods.

------

(1) For the dynamic IP address:

$ sudo nmcli conn add type bridge con-name br0 ifname br0

OR

(2) For the static IP address:

$ sudo nmcli conn add type bridge con-name br0 ifname br0 \
    ipv4.method manual \
    ipv4.address 192.168.1.7/24 \
    ipv4.gateway 192.168.1.1 \
    ipv4.dns '8.8.8.8,8.8.4.4' \
    ipv4.dns-search 'sysguides.com sysguides.kvm'

If you have a static IP address like me, then substitute your details accordingly.

Here,

  1. 192.168.1.7 is my static IP address.
  2. /24 is CIDR notation for a subnet mask of 255.255.255.0
  3. 192.168.1.1 is the default gateway.
  4. 8.8.8.8 and 8.8.4.4 are IP addresses of Google Public DNS Service.
  5. sysguides.com and sysguides.kvm are my local domains that will be added to my DNS query.

------

Next, add the ethernet interface enp3s0 to the bridge br0 as a slave.

$ sudo nmcli conn add type ethernet slave-type bridge ifname enp3s0 master br0

Now, activate the bridge connection br0.

$ sudo nmcli conn up br0

Then, deactivate the ethernet interface enp3s0.

$ sudo nmcli conn down enp3s0

Display the newly created bridge connection.

$ ip -brief link show type bridge 
virbr0  DOWN  52:54:00:cd:b4:22 <NO-CARRIER,BROADCAST,MULTICAST,UP> 
br0     UP    d2:23:33:96:12:34 <BROADCAST,MULTICAST,UP,LOWER_UP>
$ ip -brief addr show dev br0
br0   UP   192.168.1.7/24 fe80::1cc:aed2:d83a:afc8/64

A network bridge has been created.

Now that the bridge has been created, you must configure KVM so that the VMs can use this new bridge interface by its name.

Create an XML file called host-bridge.xml and add the following content. I will name my host network bridge as host-bridge, but you can name it whatever you like.

$ cat host-bridge.xml
<network>
  <name>host-bridge</name>
  <forward mode='bridge'/>
  <bridge name='br0'/>
</network>

Define host-bridge as a persistent virtual network.

$ sudo virsh net-define host-bridge.xml

Activate the host-bridge network and set it to autostart on boot.

$ sudo virsh net-start host-bridge
$ sudo virsh net-autostart host-bridge

Now you can safely delete the host-bridge.xml file. It’s not required anymore.

Check if the host-bridge is up and running.

$ virsh net-list --all
 Name          State    Autostart   Persistent
------------------------------------------------
 default       active   yes         yes
 host-bridge   active   yes         yes

If you ever want to remove this network bridge and return it to its previous state, then run the following commands.

$ sudo virsh net-destroy host-bridge
$ sudo virsh net-undefine host-bridge

$ sudo nmcli conn up enp3s0
$ sudo nmcli conn down br0
$ sudo nmcli conn del br0
$ sudo nmcli conn del bridge-slave-enp3s0

9. Install virtIO drivers for Windows guests (Optional)

VirtIO drivers are para-virtualized drivers for KVM. VirtIO provides support for many devices including network and block (disk) devices. These drivers enhance the performance of guests, decreasing guest I/O latency and increasing throughput to near bare-metal levels.

Unfortunately, Microsoft does not provide virtIO drivers since it does not have native support for virtIO devices. If you want to create Microsoft Windows virtual machine, then you need to download the virtio-win.iso image yourself in order to make the virtIO drivers available for Windows guests running on KVM.

Fedora / Rocky Linux

$ sudo wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo \
    -O /etc/yum.repos.d/virtio-win.repo

The default enabled repo will be virtio-win-stable. If you want the latest package, then you need to enable it in the /etc/yum.repos.d/virtio-win.repo file. Under the section [virtio-win-latest], just change enabled=0 to enabled=1.

$ sudo sed -i.original \
    '/\[virtio-win-latest]/,/\[virtio-win-source]/{s/enabled=0/enabled=1/}' \
    /etc/yum.repos.d/virtio-win.repo
$ sudo dnf install virtio-win

The virtio-win.iso file will be saved under /usr/share/virtio-win/ folder.

For other Linux distributions:

$ wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso

When you create a Windows VM, you need to attach this ISO image to a CD-ROM. It includes all the virtIO drivers necessary for Windows OS installation.

For a complete list of drivers, including new and old, check out this repo.

10. Setup Cockpit Web Console for managing VMs (Optional)

The cockpit is a web-based management tool that lets you administer a Linux server within a web browser. The advantage of managing virtual machines from the web console is that you can access them from any place in the world. You only need permission to access port 9090 on the system where KVM is installed and a web browser.

Cockpit is supported in most major distributions. You also need to install cockpit-machines, which is a cockpit module for managing virtual machines.

Fedora / Rocky Linux

$ sudo dnf install cockpit cockpit-machines

Ubuntu / Debian Linux

$ sudo apt install cockpit cockpit-machines

A short description of the above packages.

  • cockpit: A tool to manage your GNU/Linux servers via a web browser.
  • cockpit-machines: A cockpit module for managing virtual machines.

Enable and start cockpit socket.

$ sudo systemctl enable --now cockpit.socket

Add cockpit service to system firewall.

Fedora / Rocky Linux

$ sudo firewall-cmd --add-service=cockpit --permanent
$ sudo firewall-cmd --reload

Ubuntu / Debian Linux

$ sudo ufw allow 9090

To access the cockpit web console, open a web browser and enter your hostname or IP address, followed by :9090 to specify port 9090. For example https://agni.sysguides.lan:9090

Warning: You may get a security warning when you first open the cockpit web console in the browser. This is because the cockpit uses a self-signed certificate to enable HTTPS. If you are connecting from a private network, you can safely ignore this warning and proceed. Otherwise, get a certificate from a certification authority like Let’s Encrypt.

Cockpit Login Page:

How to Install KVM on Linux and Run Guest OS Faster Cockpit Login

Virtual Machines Section:

How to Install KVM on Linux and Run Guest OS Faster Cockpit VMs

11. Conclusion

In this blog, you learned about the key elements of KVM virtualization and how they relate to one another. You also learned how to install KVM on Linux distribution, whether it is a server with or without GUI. Additionally, you have probably now also set up the cockpit web console, if it fits your needs.

You should now be able to begin creating virtual machines without any issues. Check out my blog on How to Install a KVM Guest OS from the Command-Line. If you wish to install guest OS using Virtual Machine Manager, check my other blog on How to Install Guest OS in Virt-Manager: A Quick Intro. In the upcoming blogs, I will show you how to create virtual machines in the cockpit web console. So, please stay tuned to this website for updates.

guest
0 Comments
Inline Feedbacks
View all comments