1. Overview

KVM (Kernel-based Virtual Machine) is a popular virtualization technology for Linux-based operating systems. Along with the QEMU hardware emulator, KVM converts Linux to a bare-metal hypervisor, allowing a host computer to run multiple separate virtual environments known as guests or virtual machines (VMs). KVM benefits directly from every new Linux feature, repair, and development since it’s part of the current Linux code.

In this tutorial, we’ll learn the essentials of setting up a KVM hypervisor on an Ubuntu 18.04 server, as well as how to create and manage KVM virtual machines using the command line.

2. KVM Installation and Configuration

KVM consists of a kernel module (kvm.ko) that provides a virtualization layer and a processor-specific module (kvm-intel.ko or kvm-amd.ko), depending on the CPU type.

2.1. Check the Virtualization Requirements

First, it’s necessary to confirm that the CPU is compatible with virtualization technology. Since KVM only functions with Intel or AMD processors, the following command enables fetching in /proc/cpuinfo for ‘vmx’ or ‘svm’ flags related respectively to Intel and AMD processor types:

$ egrep -c '(vmx|svm)' /proc/cpuinfo

If the output is larger than zero, the system has virtualization enabled. Otherwise, we need to access the server’s BIOS settings and activate the virtualization technology (Intel VT-x or AMD-v).

Then, to verify that we can run KVM virtual machines on the server, we run the kvm-ok command:

$ kvm-ok 
INFO: /dev/kvm exists 
KVM acceleration can be used

If the command doesn’t exist, it can be downloaded using the apt package cpu-checker.

2.2. Install KVM

KVM collaborates with QEMU and the libvirt library to convert a Linux system into a hypervisor (host system).

QEMU is the hardware resource emulator, whereas KVM is the kernel module that supports virtualization.

libvirt is a virtualization library that covers QEMU and KVM and provides APIs for other applications to be used, such as virt-manager (GUI to manage virtual machines), libvirtd (the system service), and virsh (the CLI tool).

It suffices to install the related packages by executing the command apt install:

$ sudo apt install -y qemu-kvm libvirt-daemon libvirt-clients bridge-utils virtinst

Now, we verify that the corresponding kernel modules are loaded with the lsmod command:

$ lsmod | grep kvm
kvm_intel             217088  0
kvm                   614400  1 kvm_intel
irqbypass              16384  1 kvm

Finally, let’s start the libvirtd daemon and check the service status with the systemctl utility:

$ systemctl start libvirtd.service
$ systemctl status libvirtd
● libvirtd.service - Virtualization daemon
   Loaded: loaded (/lib/systemd/system/libvirtd.service; enabled; vendor preset:
   Active: active (running) since Wed 2023-08-09 07:59:35 UTC; 21min ago
     Docs: man:libvirtd(8)
           https://libvirt.org
 Main PID: 1487 (libvirtd)
    Tasks: 19 (limit: 32768)
   CGroup: /system.slice/libvirtd.service
           ├─1487 /usr/sbin/libvirtd
           ├─2457 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default
           └─2458 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default

At this step, the virtualization environment is ready: the Linux system can host and manage virtual machines.

3. Manage KVM Guests From Command Line

The virt-manager, a graphical application for managing the whole virtualization environment, is one of the tools included with KVM packages. In this section, we’ll concentrate on command-line techniques, utilizing the virt-install command to add new virtual guests and the virsh tool to access and control them.

3.1. Create a Virtual Machine With virt-install

The virt-install tool builds virtual machines and installs an operating system on them using the libvirt hypervisor management library.

It’s possible to automate the installation of virtual machines by using virt-install either interactively or as part of a script. It allows launching an installation from a local ISO, a remote repository, or a live CD image. We may also use a PXE boot (Preboot Execution Environment), which is a network boot protocol that allows a local computer to boot from data located on a remote server rather than booting from the local disk.

The parameters we provided in the following setup are only the bare minimum required for a functional configuration. It represents a CentOS virtual machine with 4GB of memory, 2 virtual processors, and 15GB of disk storage created from a network installation media:

$ virt-install \
--name=centosVM \
--ram=4096 \
--disk path=/var/kvm/images/centos7.img,size=15 \
--vcpus=2 \
--os-type=linux \
--os-variant=rhel7 \
--graphics none \
--location 'http://ftp.iij.ad.jp/pub/linux/centos/7/os/x86_64/' \
--extra-args console=ttyS0
Starting install...
Retrieving file vmlinuz... | 6.5 GB 00:17
<...>

The main attributes used above are:

  • name: the guest’s name
  • ram: the memory amount
  • disk: the storage settings like the directory path and the dedicated size.
  • vcpus: the number of virtual processors allocated to the guest
  • os-type: the operating system type
  • os-variant: the OS distribution
  • location: the link to the ISO image

Depending on the virtual machine features, many attributes and options of virt-intall are available in the official documentation.

3.2. Interact With Virtual Machines Using virsh

In order to manage the hypervisor and virtual guests, KVM provides a default management tool – virsh.

virsh considers virtual machines/guests as domains and offers a variety of commands to manage them. It requires the domain name with the specified command to execute a feature, as the following syntax shows:

$ virsh <command> <domain-name> [options]

The next part will focus on basic management tasks that virsh can provide, such as starting, shutting down, suspending, and accessing a domain.

To start an existing virtual machine, we execute virsh with the start command and the name of the required domain:

$ virsh start centosVM1     
Domain centosVM1 started

The same syntax is considered to suspend a guest domain:

$ virsh suspend centosVM1
Domain centosVM1 suspended

The system user can also use the shutdown command to stop the guest or destroy to force a shutdown on the guest:

$ virsh shutdown testvm
Domain testvm is being shutdown

The virsh command list returns the list of active guests, suspended, and stopped domains when we add the –all option:

$ virsh list --all
 Id    Name                           State
----------------------------------------------------
 2     centosVM                        running
 4     centosVM1                       paused
 -     testvm                          shut off

It’s possible also to access a guest domain with the console command. To get back to the host console, we press “Ctrl + ]” characters:

$ virsh console centosVM     
Connected to domain centosVM
Escape character is ^]     
CentOS Linux 7 (Core)
Kernel 3.10.0-123.el7.x86_64 on an x86_64
localhost login:     #Switch on Guest
Password:
Last login: Sat Aug 7 14:16:10 2023
[root@localhost ~]#     #press Ctrl + ]
[root@kvm ~]#     #Back to Host

Finally, a system user can display pieces of information about a specific guest by using dominfo command:

$ virsh dominfo centosVM
Id:             7
Name:           centosVM
UUID:           5151454b-b0f4-435b-b73b-9cc590248b51
OS Type:        hvm
State:          running
CPU(s):         1
CPU time:       237.9s
Max memory:     1048576 KiB
Used memory:    1048576 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: apparmor
Security DOI:   0
Security label: libvirt-5151454b-b0f4-435b-b73b-9cc590248b51 (enforcing)

In this part, we explored virsh‘s fundamental administration functions. For more complex activities, a wide range of commands are available.

4. Conclusion

In this article, we learned about KVM utilization on Linux systems, from setting up the virtualization environment to running virtual machines with basic settings.

As a final point, before deployment, it’s important to evaluate the goals of a virtual machine in light of a variety of aspects, including the required level of performance, the I/O types, the host’s available storage, and the network setup.