Set Up An Arch Linux Virtual Machine Under QEMU/KVM

Introduction

I’ve been intruiged by Arch Linux for a long time.  Arch Linux is such a cool distro that it is known not just for the distro itself but also for its first-class documentation which covers a comprehensive range of topics related to Linux.  Many Linux users and administrators who have never used Arch Linux have nonetheless at one time or another relied on its excellent documentation.

In wanting to test it out, the standard choices for setting up Arch Linux as a virtual machine presented themselves: Run it under Virtualbox, under VMWare, or perhaps Microsoft Hypervisor.  However I wanted to use QEMU/KVM.  On my host system I have virt-manager installed which provides a graphical user interface for setting up virtual machines under QEMU/KVM.

What are KVM and QEMU?  QEMU is an emulator which supports different CPUs and devices(1)(2) while KVM is a Linux kernel module which makes use of the CPU’s virtualization extensions.  KVM speeds up QEMU.  QEMU/KVM can be considered the native virtualization system of Linux.  It is purely open source and has excellent performance and is fairly easy to administer.

Libvirt is a set of Linux tools that enable interacting with and managing virtual machines under Linux.  From the Debian libvirt-daemon-system package description:

Libvirt is a C toolkit to interact with the virtualization capabilities of recent versions of Linux (and other OSes). The library aims at providing a long term stable C API for different virtualization mechanisms. It currently supports QEMU, KVM, XEN, OpenVZ, LXC, and VirtualBox.

One important tool to know is virsh which is part of the libvirt-clients Debian package.  From the virsh manual page:

The virsh program is the main interface for managing virsh guest domains. The program can be used to create, pause, and shutdown domains.  It can also be used to list current domains.  Libvirt is a C toolkit to interact with the virtualization capabilities of recent versions of Linux (and other OSes).

The library aims at providing a long term stable C API.  It currently supports Xen, QEMU, KVM, LXC, OpenVZ, VirtualBox and VMware ESX.

Although we are using the virt-manager graphical interface here, it is good to get to know virsh.

Setup Considerations – Network Bridge

Out-of-the-box when you run virt-manager it will set up NAT networking for your devices.  This default setup allows guests machines to either use DHCP or manual network configuration on the NAT subnet and allows the guests to communicate with the outside world, but it does not allow traffic to come into the guests.

There are various ways to configure networking for a VM environments including creating virtual switches with VDE (see the Debian vde2 package).  A straightforward way to set up networking is to create a bridge on the host machine.  There are guides on how to set up a bridge under the legacy ifupdown system.  I now use netplan on all my servers with the networkd backend and here is a network configuration .yaml that will set up a bridge br0 on a machine with an ethernet device named eno1:

network:
  version: 2
  renderer: networkd
  ethernets:
    eno1:
      match:
        macaddress: 56:d7:8f:b2:7f:3d
      dhcp4: false
      dhcp6: false
  bridges:
    br0:
      interfaces: [eno1]
      dhcp4: no
      addresses: [192.168.0.2/24]
      gateway4: 192.168.0.1
      nameservers:
        search: [mydomain.net]
        addresses: [192.168.0.1]

This allows you to assign IP addresses to virtual machines using the same subnet as the host, and those machines will be reachable to all other machines on the same subnet.  Thus, having a virtual machine running on the host will be like having a physical machine running on the same network as the host.

While I will not go into all the details for setting up netplan here I will simply add that if you do decide to use it make sure to completely remove any other network configuration systems including ifupdown, NetworkManager, connman, etc.

Use UEFI Instead of BIOS in the VM

QEMU by default uses a traditional BIOS for booting virtual machines however I prefer the more modern UEFI.  It’s 2021 and no one should be using BIOS.  Install the Debian ovmf package to have UEFI available as an alternate firmware option when setting up a VM in QEMU.

Set Up An Arch Linux Virtual Machine

First download the Arch Linux ISO image from here.  As of this writing the ISO image is named archlinux-2021.02.01-x86_64.iso

Now we get to the fun part.  First, fire up virt-manager graphical interface.  It may be listed in the menu as Virtual Machine Manager.  Select Edit -> Connection Details -> Virtual Networks and see if it has the default virbr0 device (which we are not going to use).  It’s good to know about this device even though we’re not going to use it.  Close the Connection Details window and select File -> New Virtual Machine.

Select Local install media and in the screen that comes up browse to the Arch Linux ISO image that you downloaded.

For the option “Choose the operating system you are installing” uncheck “Automatically detect from the installation media” and enter “Generic default” in the input box.

In the next window select the amount memory and number of CPUs you want to allocate.

In the next window select a size for the virtual disk.

In the next window create a name for the virtual machine.  Check the box Customize configuration before install.  Under Network selection select “Specify shared device name” and enter your bridge device (e.g. “br0”) in the Bridge name field.

Select Finish.  In the next window change Firmware to UEFI.

You can change parameters for the virtual machine’s components.  For example if you do not want sound nor USB you can disable/remove these devices.  You can set boot options such as the device boot order, whether to show a boot menu at bootup, and whether to start the virtual machine automatically whenever the host system starts.

When you are finished it should boot the Arch Linux ISO.  At the menu select the default install option.

Setting Up Arch Linux

Here is an outline of the steps necessary to set up Arch Linux inside the virtual machine:

Use the parted partitioning tool and create a new gpt partition table:

parted
mktable gpt

Set Up the Virtual Disk

Create an EFI partition, boot partition, root partition, and swap partition.  The boot partition will be formatted as ext4.  I chose to format the root partition as f2fs which is a high-performance file system intended for flash devices because my host system uses an NVME SSD drive and the root filesystem on the host is also f2fs.  I’m not sure if there’s any benefit to using f2fs in a virtual machine however it seems to work well.  The ext4 boot partition is necessary due to the fact that f2fs filesystem support may not have been compiled directly into the kernel (“m” instead of “y”) and thus not be available at bootup.

Note that you should make the boot partition a decent size since it holds the kernels and their corresponding initrd images.  If you have multiple kernels then the space can fill up – make boot at least 500 MB to accommodate having several kernels.

A good size for the EFI partition is 80M.

To perform the actual partitioning I use fdisk.  Use any partition tool you like.  Here is the layout I used:

sda1 /boot/efi  EFI       mkfs.fat -F32 /dev/sda1   80M
sda2 /boot      default   mkfs.ext4 /dev/sda2       500M
sda3 /          default   mkfs.f2fs /dev/sda3       remainder of disk - swap size
sda4 swap       swap      mkswap /dev/sda4          ?

I left a ? for the swap size – I have a VM with a small 275M swap file and it is not even being used.  Use more if you want.  The root partition should be the remainder of the disk space minus the swap size.

The filesystems must be mounted and swap activated with the swapon command:

mount /dev/sda3 /mnt
mkdir /mnt/boot
mount /dev/sda2 /mnt/boot
mkdir /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi
swapon

Install the Base System

pacstrap /mnt base linux linux-firmware

Generate the fstab filesystem table:

genfstab -U /mnt >> /mnt/etc/fstab

Chroot into the new system using the arch-chroot command:

arch-chroot /mnt

Further Setup

I’m just going to paste the rest of the commands.  These commands configure the timezone, set the system clock, install the Vim editor, set up the system locale, hostname, and localhost resolution:

ln -sf /usr/share/zoneinfo/America/Phoenix /etc/localtime

hwclock --systohc

pacman -S vim
cd /usr/bin
ln -s vim vi

vi /etc/locale.gen
# uncomment the line en_US.UTF-8 UTF-8
locale-gen


vi /etc/hostname
# enter the name, e.g. "arch"

vi /etc/hosts

# sample /etc/hosts, remove the # at the beginning of the next 3 lines
#127.0.0.1 localhost
#::1   localhost
#127.0.1.1 arch.localdomain  arch

Set Up Netplan and Name Resolution

mkdir /etc/netplan
vi /etc/netplan/01-netcfg.yaml

Here are the contents of 01-netcfg.yaml:

network:
    version: 2
    renderer: networkd
    ethernets:
        enp0s3:
            dhcp4: true

Change it if you want to use a static IP address instead.  I recommend starting with a dynamic one to test the system.

Set up DNS name resolution:

vi /etc/resolv.conf

add the following line, use the address appropriate for your network:

nameserver 192.168.0.1

Finishing the Setup

Here are the rest of the setup commands.  These create a new initramfs, set the root password, and install some important core tools and utilities and install the grub boot manager:

mkinitcpio -P

passwd

pacman -S f2fs-tools qemu-guest-agent grub efibootmgr bash-completion openssh man-pages sudo

systemctl enable sshd

groupadd -g 27 sudo  # assign the same GID to sudo that Debian uses

mkdir /boot/grub
grub-mkconfig -o /boot/grub/grub.cfg

grub-install /dev/sda

You can add a user:

useradd -m myuser

Add the user to the sudo group:

usermod -aG sudo myuser

Finally, type exit to exit the chroot.

You can now halt or reboot the system.

systemctl reboot

 

Using Pacman

Pacman is the package manager for Arch Linux.  Here are a few essential commands:

pacman -Q   list all installed
pacman -Fy  update database
pacman -Syu update all packages
pacman -Ss  search names and descriptions
pacman -Ss '^vim-'   limit to package name only
pacman -F  search file names in remote packages
pacman -Si  info on package
pacman -S netplan man-db   install packages

 

VM Guest Network Configuration

Make sure that the network interface stanza in the XML config for your new guest is similar to what is shown in this guide:

help.ubuntu.com: KVM/Networking – Converting an existing guest

That is, the type must be set to bridge and there should be a “source bridge” line, not “source network”.

References

  1. packetflow.co.uk: What Is the Difference between QEMU and KVM? by Rick Donato
  2. stratoscale.com/blog: Diferences between KVM and QEMU by Simon Grinberg

wiki.archlinux.org: Installation guide

help.ubuntu.com: KVM/Networking – Converting an existing guest


Comments

Leave a Reply