17.1 Virtual Machines
Virtual machines are based on the same concept as virtual memory, except with all of the machine’s hardware instead of just memory. In this model, you create an entirely new machine (processor, memory, I/O interfaces, and so on) with the help of software, and run a whole operating system in it—including a kernel. This type of virtual machine is more specifically called a system virtual machine, and it’s been around for decades. For example, IBM mainframes traditionally use system virtual machines to create a multiuser environment; in turn, users get their own virtual machine running CMS, a simple single-user operating system.
You can construct a virtual machine entirely in software (usually called an emulator) or by utilizing the underlying hardware as much as possible, as is done in virtual memory. For our purposes in Linux, we’ll look at the latter kind due to its superior performance, but note that a number of popular emulators support old computer and gaming systems, such as the Commodore 64 and Atari 2600.
The world of virtual machines is diverse, with a tremendous amount of terminology to wade through. Our exploration of virtual machines will focus primarily on how that terminology relates to what you might experience as a typical Linux user. We’ll also discuss some of the differences you might encounter in virtual hardware.
Fortunately, using virtual machines is far simpler than describing them. For example, in VirtualBox, you can use the GUI to create and run a virtual machine or even use the command-line VBoxManage tool if you need to automate that process in a script. The web interfaces of cloud services also facilitate administration. Due to this ease of use, we’ll concentrate more on making sense of the technology and terminology of virtual machines than the operational details.
17.1.1 Hypervisors
Overseeing one or more virtual machines on a computer is a piece of software called a hypervisor or virtual machine monitor (VMM), which works similarly to how an operating system manages processes. There are two types of hypervisors, and the way you use a virtual machine depends on the type. To most users, the type 2 hypervisor is the most familiar, because it runs on a normal operating system such as Linux. For example, VirtualBox is a type 2 hypervisor, and you can run it on your system without extensive modifications. You might have already used it while reading this book to test and explore different kinds of Linux systems.
On the other hand, a type 1 hypervisor is more like its own operating system (especially the kernel), built specifically to run virtual machines p. 403 quickly and efficiently. This kind of hypervisor might occasionally employ a conventional companion system such as Linux to help with management tasks. Even though you might never run one on your own hardware, you interact with type 1 hypervisors all the time. All cloud computing services run as virtual machines under type 1 hypervisors such as Xen. When you access a website, you’re almost certainly hitting software running on such a virtual machine. Creating an instance of an operating system on a cloud service such as AWS is creating a virtual machine on a type 1 hypervisor.
In general, a virtual machine with its operating system is called a guest. The host is whatever runs the hypervisor. For type 2 hypervisors, the host is just your native system. For type 1 hypervisors, the host is the hypervisor itself, possibly combined with a specialized companion system.
17.1.2 Hardware in a Virtual Machine
In theory, it should be straightforward for the hypervisor to provide hardware interfaces for a guest system. For example, to provide a virtual disk device, you could create a big file somewhere on the host and provide access as a disk with standard device I/O emulation. This approach is a strict hardware virtual machine; however, it is inefficient. Making virtual machines practical for a variety of needs requires some changes.
Most of the differences you might encounter between real and virtual hardware are a result of a bridging that allows guests to access host resources more directly. Bypassing virtual hardware between the host and guest is known as paravirtualization. Network interfaces and block devices are among the most likely to receive this treatment; for example, a /dev/xvd device on a cloud computing instance is a Xen virtual disk, using a Linux kernel driver to talk directly to the hypervisor. Sometimes paravirtualization is used for the sake of convenience; for example, on a desktop-capable system such as VirtualBox, drivers are available to coordinate the mouse movement between the virtual machine window and the host environment.
Whatever the mechanism, the goal of virtualization is always to reduce the problem just enough so that the guest operating system can treat the virtual hardware as it would any other device. This ensures that all of the layers on top of the device function properly. For example, on a Linux guest system, you want a kernel to be able to access virtual disks as block devices so that you can partition and create filesystems on them with the usual tools.
Virtual Machine CPU Modes
Most of the details about how virtual machines work are beyond the scope of this book, but the CPU deserves a mention because we’ve already talked about the difference between kernel mode and user mode. The specific names of these modes vary depending on the processor (for example, the x86 processors use a system called privilege rings), but the idea is always the same. In kernel mode, the processor can do almost anything; in user mode, some instructions are not allowed, and memory access is limited.
The first virtual machines for the x86 architecture ran in user mode. This presented a problem, because the kernel running inside the virtual machine wants to be in kernel mode. To counter this, the hypervisor can detect and react to (“trap”) any restricted instructions coming from a virtual machine. With a little work, the hypervisor emulates the restricted instructions, enabling virtual machines to run in kernel mode on an architecture not designed for it. Because most of the instructions a kernel executes aren’t restricted, those run normally, and the performance impact is fairly minimal.
Soon after the introduction of this kind of hypervisor, processor manufacturers realized that there was a market for processors that could assist the hypervisor by eliminating the need for the instruction trap and emulation. Intel and AMD released these feature sets as VT-x and AMD-V, respectively, and most hypervisors now support them. In some cases, they are required.
If you want to learn more about virtual machines, start with Jim Smith and Ravi Nair’s Virtual Machines: Versatile Platforms for Systems and Processes (Elsevier, 2005). This also includes coverage of process virtual machines, such as the Java virtual machine (JVM), which we won’t discuss here.
17.1.3 Common Uses of Virtual Machines
In the Linux world, virtual machine use often falls into one of a few categories:
Testing and trials There are many use cases for virtual machines when you need to try something outside of a normal or production operating environment. For example, when you’re developing production software, it’s essential to test software in a machine separate from the developer’s. Another use is to experiment with new software, such as a new distribution, in a safe and “disposable” environment. Virtual machines allow you to do this without having to purchase new hardware.
Application compatibility When you need to run something under an operating system that differs from your normal one, virtual machines are essential.
Servers and cloud services As mentioned earlier, all cloud services are built on virtual machine technology. If you need to run an internet server, such as a web server, the quickest way to do so is to pay a cloud provider for a virtual machine instance. Cloud providers also offer specialized servers, such as databases, which are just preconfigured software sets running on virtual machines.
17.1.4 Drawbacks of Virtual Machines
For many years, virtual machines have been the go-to method of isolating and scaling services. Because you can create virtual machines through a p. 405 few clicks or an API, it’s very convenient to create servers without having to install and maintain hardware. That said, some aspects remain troublesome in day-to-day operation:
- It can be cumbersome and time-consuming to install and/or configure the system and application. Tools such as Ansible can automate this process, but it still takes a significant amount of time to bring up a system from scratch. If you’re using virtual machines to test software, you can expect this time to accumulate quickly.
- Even when configured properly, virtual machines start and reboot relatively slowly. There are a few ways around this, but you’re still booting a full Linux system.
- You have to maintain a full Linux system, keeping current with updates and security on each virtual machine. These systems have systemd and sshd, as well as any tools on which your application depends.
- Your application might have some conflicts with the standard software set on a virtual machine. Some applications have strange dependencies, and they don’t always get along well with the software found on a production machine. In addition, dependencies like libraries can change with an upgrade in the machine, breaking things that once worked.
- Isolating your services on separate virtual machines can be wasteful and costly. The standard industry practice is to run no more than one application service on a system, which is robust and easier to maintain. In addition, some services can be further segmented; if you run multiple websites, it’s preferable to keep them on different servers. However, this is at odds with keeping costs down, especially when you’re using cloud services, which charge per virtual machine instance.
These problems are really no different from the ones you’d encounter running services on real hardware, and they aren’t necessarily impediments in small operations. However, once you start running more services, they’ll become more noticeable, costing time and money. This is when you might consider containers for your services.