Virtual Machines in Linux

This is a brief introduction to setting up and running Virtual Machines in Linux. While there are several different options to accomplish this, my preferred method is using KVM + QEMU + LibVirt. Here’s what each of these does: QEMU is a full-fledged stand-alone emulator that can emulate all kinds of hardware for virtual machines to utilize and run on. Technically, you can create and run VMs on Linux with just QEMU and you don’t need KVM or Libvirt. However, all of the emulation is done in software and as a result can be pretty slow. Enter KVM – KVM is a kernel module and Linux Hypervisor. It essentially provides a sped-up, near-native layer that works along with processor support for virtualization and can be utilized by QEMU to provide a much more performant VM experience. Libvirt is an API layer that can be used to create and manage VMs that run on QEMU+KVM. It also supports a variety of front-end UI that can be used for the creation and management of VMs with Virt-Manager being the standard one that I utilize.

The basic requirements for creating and running VMs on Linux are a virtualization capable processor (at this time, almost all mainstream AMD and Intel processors released in the past several years come with native virtualization support – typically called vt-x) and KVM, QEMU, LibVirt packages.

Step 1: Enable virtualization extensions in your UEFI/BIOS

Before starting, you need to ensure that your processor’s vt-x capabilities are enabled in your UEFI/BIOS – boot into your UEFI/BIOS (systemctl reboot --firmware-setup on systemd based distributions will put you into your UEFI/BIOS without key mashing during boot time).

Step 2: Check KVM is installed and available

KVM is a kernel module and is typically installed as part of the base Linux system in many distributions. You can run lsmod | grep kvm to see if it is already installed and loaded by your kernel.

Step 3: Install the QEMU, LibVirt and Virt-Manager packages for your distribution

QEMU typically has a lot of package options and on Arch based distributions if you only plan to run desktop OS on your VMs you can choose QEMU-Desktop package which will install everything needed for running desktop VMs. virt-manager will provide a UI that allows you to create and manage VMs.

Step 4: Create a bridge network

libvirt will create a default network which is a NAT network for your VMs inside the physical host. Think of it as a router in front of your VMs with your physical host network acting as the broadband connection to the Internet allowing your VMs to access the Internet. However, this default network will not allow you to access your VMs from your physical LAN or your VMs to access your physical LAN. If you are ok with this restriction, you don’t need to do anything in this step. But if you want your VMs to essentially act like just another machine on your physical LAN you need to create a bridge network. If you are on a NetworkManager based distro (Manjaro is one and the distro that I currently use for my Linux desktop) then you can use nmcli tool to create the bridge network. A bridge network essentially acts like a virtual ethernet switch to which your physical host and all the VMs hosted into it are plugged in. Here are the set of commands to run to create a bridge network:

# Get your current connections - we will replace the wired connection with a bridge
# Note that wireless connections cannot be used to create a bridge at this time
nmcli con show # note down the name, UUID and Device of your wired connection
# Create a bridge connection. Substitute br0 with name you want for your bridge interface and bridge connection
nmcli con add ifname br0 type bridge con-name br0
# Add your physical ethernet device as slave to bridge
nmcli con add type bridge-slave ifname <wired device name>
# Down the wired connection
nmcli con down <wired connection name> # Alternatively, use the UUID
# Delete the wired connection
nmcli con del <wired connection name>
# Bring up the bridge network
nmcli con up br0
# Check the ip addresses for your network
# If everything worked, br0 should have an ip address and your
# wired interface should not
ip a s

Step 5: Add your user account to libvirt group. Log out and log back in for the change to take effect.

In order to be able to create and manage VMs, add your user to the libvirt group. sudo usermod -a -G libvirt <username>

Step 6: Enable libvirtd service so it starts automatically on every boot

sudo systemctl enable libvirtd

Step 7: Enable XML editing in virt-manager

If you are using virt-manager, launch it and after connecting to the local qemu:///system, click on Edit > Preferences > General Preferences > Enable XML Editing to enable XML editing. While I use the virt-manager UX for most things, advanced changes are only possible by directly editing the XML configuration.

Step 8: Create a network for your VMs using the bridge network from Step 5

In virt-manager, click on Edit > Connection Details > Virtual Networks > + to add a new network. Click on XML and change it to look like this:

<network>
  <name>host-bridge</name>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>

Step 9: Create your VM

There are many tutorials that go through the creation of a VM – here’s a pretty comprehensive one that goes through all the steps in setting up a Windows VM. I typically use an XML template and edit that directly to create the VM configuration that I want. Remember to use the network created in Step 9 as source network.

Other useful software

I find these software useful to view/administer/connect to the VMs – KRDC for remote connections to the VMs, virt-viewer also for the same purpose but connecting to the machine at a different layer so you can view it through the boot process.

Leave a Reply

Your email address will not be published. Required fields are marked *