Skip to content

102.6 Linux as a virtualization guest

Introduction

Virtual machines (VMs) are simulated computers. You can use them to create new computers on top of your running machine and install new operating systems there. In some cases it is also possible to run only parts of an OS on top of the current OS. This is called having containers.

To run virtual machines we need Hypervisor software, also called a Virtual Machine Manager (VMM). The machine running the hypervisor is the host. The machines running inside it are the guests.

The hypervisor manages the physical hardware's resources and shares them between the guests. A virtual machine has many parts of a real computer emulated in software, like the BIOS and the disk controllers. It usually uses hard disk images stored as normal files, and gets access to the host's RAM and CPU through the hypervisor.

To check if your CPU supports virtualization, look for vmx (Intel CPUs) or svm (AMD CPUs) in the flags line of /proc/cpuinfo:

grep --color -E "vmx|svm" /proc/cpuinfo

You may need to turn the hypervisor option On using your BIOS or UEFI.

Based on your CPU you should have kvm or kvm-amd kernel modules loaded:

lsmod | grep -i kvm
sudo modprobe kvm

If you see hypervisor in your /proc/cpuinfo it means that you are inside a virtualized Linux machine.

Moving a virtual machine from one hypervisor to another is called a migration. Some migrations need the guest to be fully shut down first. Others can be done while the guest is still running, which is called a live migration. This is useful during maintenance, or when a hypervisor stops working and the guest must be moved to a working one.

Host machine (real hardware)
    |
    +-- Hypervisor software
          |
          +-- Guest 1 (full OS, own kernel, own BIOS)
          +-- Guest 2 (full OS, own kernel, own BIOS)
          +-- Guest 3 (full OS, own kernel, own BIOS)

Type 2 Hypervisor

These hypervisors run on a normal operating system, just like any other program. A guest operating system runs as a process on the host. The type 2 hypervisor is the software sitting between the guest and the host.

Two of the most famous Type 2 hypervisors are VirtualBox (from Oracle) and VMware.

Type 1 Hypervisor

These hypervisors run directly on the host's hardware, controlling the hardware and managing the guests themselves. For this reason they are called bare-metal hypervisors. The first hypervisors, developed by IBM in the 1960s, were of this type.

Some of the most famous Type 1 hypervisors are KVM, Xen and Hyper-V. KVM is built into Linux since kernel version 2.6.20.

Type 2 (VirtualBox, VMware)        Type 1 (Xen, Hyper-V)
──────────────────────────         ──────────────────────
  Guest OS                           Guest OS
  Hypervisor                         Hypervisor
  Host OS  (normal Linux/Windows)    Hardware  (no host OS)
  Hardware

A note on KVM specifically: the PDF describes it as both Type-1 and Type-2. It needs a normal Linux OS to work, but it becomes part of the kernel itself, so it acts like a bare-metal hypervisor. VMs made with KVM are created and managed with the libvirt daemon and its tools.

Types of virtual machines

The PDF describes three types of guests:

Type Description
Fully virtualized The guest does not know it is a virtual machine. No special drivers are installed inside it. Needs Intel VT-x or AMD-V CPU extensions enabled in BIOS/UEFI
Paravirtualized (PVM) The guest knows it is a virtual machine. It uses a modified kernel and special guest drivers to work better with the hypervisor. Usually faster than fully virtualized
Hybrid A mix of both. An unmodified guest OS gets paravirtualized drivers for disk and network, so it gets near-native speed for input/output

KVM uses drivers from the Virtio project. VirtualBox uses Guest Extensions, available as a downloadable ISO image.


Creating a Virtual Machine

First, create the machine itself. We tell the hypervisor how much RAM, disk and CPU this machine needs, and give it a name. Then we need to install the guest OS. This can be done using:

  • Installing from a CD / DVD
  • Cloning an existing machine
  • Using Open Virtualization Format (OVF) to move machines between hypervisors. This is a standard format for virtual machine definition and may include several files. In this case you can archive all of them into one Open Virtualization Archive (OVA) file
  • Creating Templates, which are master copies used to start new machines

You may need to install some guest drivers or additions to help your hypervisor control your guest machine better. These might include graphical drivers for VirtualBox, or scripts to help VMware control a guest machine and check its status.

Disk image types

The PDF describes two main types of virtual disk:

Type Description
COW (Copy-on-write) Also called thin-provisioning or sparse. The file has a maximum size, but only grows as real data is written. The guest may see a 23.3 GB disk while the file on the host is only 5.5 GB. The qcow2 format used by QEMU is this type
RAW The full space is reserved from the start. A 10 GB raw disk uses 10 GB on the host immediately. Faster, because the hypervisor never has to grow the file while writing

Guest-specific configs

Some configurations are machine specific. For example, a network card's MAC address must be unique on the whole network. If we are cloning a machine, or creating machines from templates, we need to change these on each machine before booting them:

  • Host Name
  • NIC MAC Address
  • NIC IP (if not using DHCP)
  • Machine ID (delete /etc/machine-id and /var/lib/dbus/machine-id, then run dbus-uuidgen --ensure. These two files might be soft links to each other)
  • Encryption Keys like SSH Fingerprints and PGP keys
  • HDD UUIDs
  • Any other UUIDs on the system

Some configs might be empty on templates. Do not forget to fill them too.

The D-Bus machine ID

Many Linux installations create a machine identification number at install time, called the D-Bus machine ID. If a virtual machine is cloned, a new ID must be created, so the hypervisor sends resources to the right guest.

Check that an ID exists (no error message means it exists):

dbus-uuidgen --ensure

View the current ID:

$ dbus-uuidgen --get
17f2e0698e844e31b12ccd3f9aa4d94a

No two Linux systems on a hypervisor should have the same D-Bus machine ID.

The ID is stored at /var/lib/dbus/machine-id, which is normally a symbolic link to /etc/machine-id. Changing this on a running system is discouraged, as crashes are likely. If two VMs do have the same ID, generate a new one:

sudo rm -f /etc/machine-id
sudo dbus-uuidgen --ensure=/etc/machine-id

If /var/lib/dbus/machine-id is not a symbolic link back to /etc/machine-id, it needs to be removed as well.

SSH host keys and access

The most common way to reach a cloud guest is OpenSSH. The admin creates a key pair:

ssh-keygen

The private key stays on the admin's local machine in ~/.ssh/. The public key is copied to the remote machine:

ssh-copy-id -i <public_key> user@cloud_server

This records the public key in ~/.ssh/authorized_keys on the cloud server and sets the right permissions on the file.

If there is only one public key file in ~/.ssh/, the -i switch can be left out. ssh-copy-id will use the .pub file by default.

Permissions for SSH keys must be 0600 for a private key and 0644 for a public key.


Containers

In the previous sections we were dealing with complete guest operating systems. It is also possible to virtualize only parts of an OS. This is called OS-level virtualization.

OS-level virtualization is a system where the kernel allows several isolated user-space instances to exist. These are called containers.

This can be used to run a single application, a service, or even most parts of a new OS for testing.

The key difference from a virtual machine: a VM emulates an entire computer, while a container uses just enough software to run an application. So a container has much less overhead.

Virtual machines                    Containers
────────────────                    ──────────
  App                                 App
  Full guest OS + kernel              (shares the host kernel)
  Hypervisor                          Container engine
  Host OS                             Host OS
  Hardware                            Hardware

Containers are also more flexible. A VM sometimes needs to be powered off before it can be migrated, but a container keeps running while it is being moved. Containers also make it easy to run a new version of an application next to the old one. As users close their sessions, the old containers are removed automatically and replaced with the new version, which reduces downtime.

Containers use the control groups (cgroups) feature of the Linux kernel. A cgroup is a way to divide system resources like memory, processor time, disk and network bandwidth for one application or a group of applications.

The PDF states directly that knowledge of cgroups is not necessary for passing the LPIC-1 exam, and that the exact implementation of container software is beyond the scope of the exam. Container technologies include Docker, Kubernetes, LXD/LXC, systemd-nspawn and OpenShift.


IaaS

Infrastructure as a Service (IaaS) means moving parts of your infrastructure to another company. You buy services like electricity, cooling, and running hypervisors from them, and just rent your virtual machine. This makes life easier, because "adding a new hard disk" now only means paying a bit more, instead of buying a disk and installing it. This is called the cloud. You might even move your machine from one continent to another with one click.

Samples of these cloud providers are Amazon Web Services, Google Cloud Platform, and Microsoft Azure.

Different cloud providers offer different levels of infrastructure or services. Some examples:

  • Load Balancing: distribute incoming requests between your servers
  • Block Storage: providing disks to be configured by you and added to your machines
  • Object Storage: lets you store your data directly, for example photos
  • Elasticity: lets you configure an automatic increase or decrease in your service capacity based on request volume
  • SaaS: Software as a Service lets you use the software you need on the cloud as a service. Think of having an online office suite for your company without installing anything on your workstations

The PDF adds three key elements an admin should watch in an IaaS deployment:

Element What to know
Computing instances Many providers charge by CPU time used, and by how many VMs are running at once. Planning this keeps costs manageable
Block storage Cost changes with the amount used and the speed. Faster storage costs more. Archive storage ("at rest") is usually very cheap
Networking Providers give web tools to set up routes, subnets and firewalls. Some offer DNS so public FQDNs can be assigned. Hybrid solutions can link an existing office network to the cloud through a VPN

cloud-init

There are programs like cloud-init which help you set up your cloud machine easily. This service can start machines based on templates on AWS, Azure, Digital Ocean and others.

It is a vendor-neutral tool, so the same setup works across many providers. It uses plain-text YAML files. With them an admin can pre-configure network settings, package selections, SSH keys, user accounts, locale settings and more.

During the first boot of a new system, cloud-init reads the settings from the YAML file and applies them. This only happens on the initial setup, which makes deploying many new systems easy.

The YAML syntax used with cloud-init is called cloud-config. A sample file:

#cloud-config
timezone: Africa/Dar_es_Salaam
hostname: test-system
# Update the system when it first boots up
apt_update: true
apt_upgrade: true
# Install the Nginx web server
packages:
 - nginx

Note that on the top line there is no space between the hash symbol (#) and the term cloud-config.

cloud-init is not only for virtual machines. It can also pre-configure containers, such as LXD Linux containers, before deployment.


Summary

I have a Linux system that can run inside a virtual machine, or host other machines itself. To run VMs I need a hypervisor. A Type 2 hypervisor like VirtualBox or VMware runs on top of a normal OS. A Type 1 hypervisor like Xen or Hyper-V runs directly on the hardware with no host OS underneath. KVM sits in between, since it is part of the Linux kernel itself. To check if my CPU can do this at all, I look for vmx (Intel) or svm (AMD) in /proc/cpuinfo.

A guest can be fully virtualized (it does not know it is a VM, and needs VT-x or AMD-V enabled in the firmware), paravirtualized (it knows, and uses special guest drivers to run faster), or a hybrid of both. Disk images come as COW (grows as data is written, like qcow2) or RAW (full size reserved from the start, but faster).

The most important practical part is what to change after cloning a machine or building one from a template. Every machine on a network must be unique, so I have to change the hostname, the MAC address, the IP if not using DHCP, the SSH host keys, any disk UUIDs, and the D-Bus machine ID. For that last one I delete /etc/machine-id and run dbus-uuidgen --ensure=/etc/machine-id, and I can check the current value any time with dbus-uuidgen --get.

Containers are a lighter option. Instead of emulating a whole computer, they share the host kernel and only carry enough software to run one application. They use cgroups in the kernel to divide up memory, CPU and bandwidth. In the cloud (IaaS), I access guests over SSH using ssh-keygen and ssh-copy-id, and I can pre-configure a new machine before its first boot using cloud-init with a YAML cloud-config file.