How to Install and Configure KVM on Ubuntu
KVM (Kernel-based Virtual Machine) is an open-source virtualization technology that empowers you to create and run virtual machines (VMs) directly on your Linux system. It leverages the Linux kernel itself, turning it into a hypervisor. KVM requires hardware virtualization support, a feature present in most modern CPUs from Intel (VT-x) and AMD (AMD-V).
In this comprehensive guide, we’ll delve into how to install and configure KVM on Ubuntu 20.04/22.04. We will cover the following steps:
- Checking hardware virtualization support.
- Installing the necessary KVM packages.
- Loading the required kernel modules.
- Setting up the KVM user group.
- Creating a KVM virtual machine using the command line interface (CLI).
- Creating a KVM virtual machine using the graphical user interface (GUI) with Virt Manager.
- Managing KVM virtual machines.
- Optimizations and best practices for KVM.
By the end of this guide, you will have KVM installed and configured, and you will have created virtual machines using both CLI and GUI methods. Let’s get started!
Prerequisites
Before we install KVM, let’s go over the prerequisites:
- A running Ubuntu 20.04/22.04 system.
- A user account with sudo privileges.
- Hardware virtualization support in your CPU.
- Virtualization enabled in BIOS/UEFI settings.
To verify that your CPU supports hardware virtualization, run this command:
$ egrep -c '(vmx|svm)' /proc/cpuinfo
If the output is 1 or greater, your CPU supports hardware virtualization.
You also need to ensure virtualization is enabled in BIOS. Reboot your system, enter BIOS setup, and enable Intel VT-x/AMD-V.
Now let’s move on to installing KVM.
Install KVM and Other Required Packages
We need to install a few packages to use KVM. Run these commands to install KVM and other required utilities:
$ sudo apt update
$ sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager
This installs the main packages:
qemu-kvm
: The core KVM package providing the virtualization functionality.libvirt-daemon-system
: The libvirt daemon, which manages virtual machines.libvirt-clients
: Command-line tools for managing libvirt.bridge-utils
: Utilities for creating and managing bridge devices for networking.virt-manager
: A graphical user interface for managing virtual machines.
Verify the installation by checking the version of KVM:
$ kvm --version
The output should display the installed KVM version:
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.28)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
Now KVM and related utilities are installed. Next we’ll load the required kernel modules.
Load KVM Kernel Modules
KVM requires the kvm
and kvm_intel
/kvm_amd
kernel modules to be loaded.
Check if they are loaded:
$ lsmod | grep kvm
If they are not loaded, run:
$ sudo modprobe kvm
$ sudo modprobe kvm_intel
This loads kvm
and kvm_intel
modules. Verify they are now loaded:
$ lsmod | grep kvm
The output should show the modules:
kvm_intel 204800 0
kvm 593920 1 kvm_intel
KVM modules are now loaded and ready to use.
Set Up KVM User Group
For better security and access control, we will create a dedicated KVM group and add users to it.
Create a kvm
group:
$ sudo groupadd kvm
Add your user to kvm
group:
$ sudo usermod -aG kvm $USER
Add any other users who need KVM access to the kvm
group as well.
Now we can continue with creating virtual machines.
Create a KVM Virtual Machine (CLI)
Let’s create a KVM virtual machine using command line tools.
We will perform the following steps:
- Create a disk image for the VM.
- Configure network bridging.
- Define the VM resources using an XML definition file.
- Start the VM installation.
First, create a disk image that will be used for VM storage:
$ sudo qemu-img create -f qcow2 /var/lib/libvirt/images/ubuntu-20.qcow2 10G
This creates a qcow2 format disk image at /var/lib/libvirt/images/ubuntu-20.qcow2 with 10GB capacity.
Next, we need to create a network bridge so the VM can connect to the network.
Edit /etc/netplan/00-installer-config.yaml
and add a network bridge:
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: no
enp0s8:
dhcp4: yes
bridges:
br0:
interfaces: [enp0s3]
dhcp4: no
addresses: [192.168.122.1/24]
gateway4: 192.168.122.1
nameservers:
addresses: [8.8.8.8,1.1.1.1]
This bridges the enp0s3 interface and assigns it an IP address of 192.168.122.1.
Apply the configuration:
$ sudo netplan apply
Now we have storage and networking ready. Let’s define the VM resources using a CLI definition file called ubuntu-vm.xml:
$ sudo nano ubuntu-vm.xml
Add this content:
<domain type='kvm'>
<name>ubuntu-vm</name>
<memory unit='GiB'>2</memory>
<vcpu>2</vcpu>
<os>
<type arch='x86_64'>hvm</type>
</os>
<devices>
<disk type='file' device='disk'>
<source file='/var/lib/libvirt/images/ubuntu-20.qcow2'/>
<target dev='vda'/>
</disk>
<interface type='bridge'>
<source bridge='br0'/>
</interface>
<graphics type='vnc' listen='0.0.0.0' port='-1'/>
</devices>
</domain>
This defines a KVM domain with:
- Name: ubuntu-vm
- Memory: 2GB
- vCPUs: 2
- Disk image: /var/lib/libvirt/images/ubuntu-20.qcow2
- Network: bridged to br0
- Graphics: VNC
Now let’s launch the VM installation:
$ sudo virt-install --import --name ubuntu-vm --ram 2048 --disk /var/lib/libvirt/images/ubuntu-20.qcow2,size=10 --vcpus 2 --os-type linux --os-variant ubuntu20.04 --network bridge=br0 --graphics vnc --noautoconsole --print-xml > ubuntu-vm.xml
$ sudo virsh define ubuntu-vm.xml
$ sudo virsh start ubuntu-vm
This will start the Ubuntu 20.04 installation from the ISO image. You can connect to the VNC console to complete the installation.
After installation completes and the VM boots up, verify it is running:
$ sudo virsh list
The output will show the running VM:
Id Name State
----------------------------------------------------
2 ubuntu-vm running
We have successfully created a KVM virtual machine using CLI tools!
Create a KVM Virtual Machine (GUI)
We can also use a GUI like Virt Manager to manage KVM VMs.
Install Virt Manager if you haven’t already:
$ sudo apt install virt-manager
Launch Virt Manager either from the command line or desktop environment.
Click on Create a new virtual machine to begin the New VM wizard.
Step through the wizard to define the VM resources, storage, network, etc.
For example, select import existing disk image, enter the path to the qcow2 image created earlier e.g. /var/lib/libvirt/images/ubuntu-20.qcow2
.
Complete the remaining steps, review the summary, and click Finish to create the VM.
The VM should now be created and powered off. Right click on it and select Run to start it.
Connect to the VNC console to complete OS installation.
We have now created a KVM virtual machine using the graphical virt-manager tool. Using the GUI can help simplify managing multiple VMs.
Manage KVM Virtual Machines
Now we have KVM installed and VMs created, let’s go over managing the VMs.
List all VMs:
$ sudo virsh list --all
This will list all active and inactive VMs.
Start a VM:
$ sudo virsh start ubuntu-vm
Shutdown a VM:
$ sudo virsh shutdown ubuntu-vm
Force power off a VM:
$ sudo virsh destroy ubuntu-vm
Delete a VM:
$ sudo virsh undefine ubuntu-vm
This will delete the VM configuration, but won’t delete the disk image.
Suspend/resume a VM:
$ sudo virsh suspend ubuntu-vm
$ sudo virsh resume ubuntu-vm
Reboot a VM:
$ sudo virsh reboot ubuntu-vm
Connect to VNC console:
$ sudo virt-viewer ubuntu-vm
This will open a VNC window to interact with the VM’s graphical console.
VM status:
$ sudo virsh domstate ubuntu-vm
VM statistics:
$ sudo virsh domstats ubuntu-vm
This covers the basic VM management tasks with KVM. You can refer to the virsh man pages for more advanced management operations.
Optimizations and Best Practices
Here are some tips for optimizing KVM performance and efficiency:
- Use the virtio drivers: Virtio drivers provide optimized I/O performance for virtual machines.
- Allocate sufficient RAM: Ensure VMs have enough RAM to avoid swapping.
- Use a fast storage backend: SSDs or NVMe drives provide better performance than traditional HDDs.
- Enable CPU pinning: Pinning VMs to specific CPU cores can improve performance by reducing context switching.
- Monitor VM performance: Regularly monitor VM performance to identify bottlenecks.
- Keep the host system updated: Regularly update the host system to ensure you have the latest security patches and performance improvements.
- Use a dedicated network interface: Using a dedicated network interface for your VMs can improve network performance.
Following best practices helps ensure your KVM infrastructure remains secure, stable and scalable.
Conclusion
We have installed KVM on Ubuntu 20.04/22.04, created VMs using CLI and Virt Manager, and covered managing and optimizing KVM.
KVM provides an open-source and cost-effective virtualization solution on Linux. With its excellent performance and wide adoption, it is a great hypervisor for running Linux guest VMs.
We encourage you to further explore KVM capabilities and build robust virtualized environments. This will allow you to consolidate servers, isolate services, and take advantage of powerful VM management features.
Alternative Solutions for Virtualization on Ubuntu
While KVM is a robust and widely used virtualization solution, other viable alternatives exist. Here are two such options, along with explanations and code examples where applicable:
1. Docker Containers:
Docker, while not a traditional hypervisor like KVM, offers a powerful and lightweight approach to virtualization through containerization. Instead of virtualizing the entire operating system, Docker packages applications and their dependencies into isolated containers that share the host OS kernel. This results in significantly reduced overhead, faster startup times, and improved resource utilization compared to KVM-based VMs.
-
Explanation: Docker containers offer application-level virtualization. Each container runs as an isolated process in userspace on the host operating system. Docker leverages the host OS kernel’s resource isolation features (namespaces and cgroups) to provide isolation. Because containers share the host kernel, they are much smaller and faster to start than full VMs. This makes them ideal for microservices architectures and continuous integration/continuous deployment (CI/CD) pipelines. Docker is a good alternative to KVM when you need to run multiple instances of an application, or when you want to deploy applications quickly and easily. Docker also simplifies dependency management by packaging all dependencies within the container.
-
Installation and Usage:
# Install Docker sudo apt update sudo apt install docker.io # Start and enable Docker service sudo systemctl start docker sudo systemctl enable docker # Verify installation docker --version # Run a simple container (e.g., Ubuntu) docker run -it ubuntu bash
This sequence installs Docker, starts the service, and runs an interactive Ubuntu container. Inside the container, you’ll have a shell prompt, allowing you to install software and run commands as if you were in a standalone Ubuntu environment, but sharing the host kernel.
-
Example Dockerfile (for creating custom containers):
# Use an official Ubuntu base image FROM ubuntu:latest # Update the package list RUN apt-get update # Install some software RUN apt-get install -y nginx # Expose port 80 EXPOSE 80 # Start nginx when the container starts CMD ["nginx", "-g", "daemon off;"]
This Dockerfile defines a container based on Ubuntu, installs Nginx web server, exposes port 80, and starts Nginx when the container launches. You can build and run this image with:
docker build -t my-nginx-image . docker run -d -p 80:80 my-nginx-image
This builds an image named
my-nginx-image
and then runs a container based on that image, mapping port 80 on the host to port 80 inside the container.
2. LXC/LXD (Linux Containers):
LXC (Linux Containers) and its successor LXD provide a system container virtualization solution that’s lighter weight than full VMs but offers more isolation than Docker. LXC/LXD creates containers that are more like lightweight virtual machines, each with its own private process space, filesystem, and network interface. While still sharing the host kernel, LXC/LXD containers offer stronger isolation than Docker, making them suitable for running entire operating systems or complex applications that require a more traditional OS environment.
-
Explanation: LXC/LXD leverages the same kernel features as Docker (namespaces and cgroups) but provides a more complete OS-level virtualization. Each container has its own root filesystem, user accounts, and system processes. This allows you to run different Linux distributions within containers on the same host, something that is not easily achievable with Docker. LXC/LXD is a good alternative to KVM when you need to run full Linux distributions, but you want to avoid the overhead of a full virtual machine. It’s often used for testing, development, and running legacy applications. LXD simplifies the management of LXC containers with a REST API and command-line tools.
-
Installation and Usage:
# Install LXD sudo snap install lxd # Initialize LXD (follow the prompts) sudo lxd init # Launch a container (e.g., Ubuntu 20.04) lxc launch ubuntu:20.04 my-container # List containers lxc list # Get a shell inside the container lxc exec my-container bash
This installs LXD via snap (a package manager developed by Canonical), initializes it, launches an Ubuntu 20.04 container named "my-container", and gives you a shell inside the container.
-
Configuration Example (profiles for resource limits):
LXD uses profiles to manage container configuration. You can create profiles to limit resources like CPU and memory.
# Create a new profile lxc profile create limited-profile # Edit the profile lxc profile edit limited-profile
This opens a YAML editor. Add the following to limit CPU and memory:
config: limits.cpu: "1" # Limit to 1 CPU core limits.memory: 1GB # Limit to 1 GB of memory description: Limited resources profile name: limited-profile used_by: []
Then apply the profile to a container:
lxc profile apply my-container limited-profile
Both Docker and LXC/LXD offer compelling alternatives to KVM for specific use cases. Docker excels in application-level virtualization and microservices, while LXC/LXD provides a lighter-weight alternative to full VMs with stronger OS-level isolation. The choice depends on the specific requirements of your virtualization needs.