1.1 系统虚拟化基本概念

虚拟化(Virtualization)泛指将物理资源抽象成虚拟资源,并在功能和性能等方面接近物理资源的技术,即“功能不缺失性能不损失”。虚拟化技术广泛应用于从硬件到软件的不同计算机系统层次,例如物理内存抽象成虚拟内存,设备抽象成文件,物理显示器抽象成窗口(Window),Java应用运行于JVM(Java Virtual Machine,Java虚拟机)。一般而言,计算机系统自下而上被划分为多个层次(见图1-1)。

图1-1 计算机系统的抽象层次和对应接口

(1)硬件向上对软件提供的指令集抽象ISA(Instruction Set Architecture,指令集架构)通常分为系统ISA(System ISA)和用户ISA(User ISA)。系统ISA提供特权操作(如切换进程页表),一般在操作系统内核态运行;用户ISA提供给普通应用程序使用(如进行加法操作),一般在用户态运行。例如,RISC-V的指令集手册提供第一卷——用户态ISA(User-Level ISA)和第二卷——特权(系统)架构(Privileged Architecture),分别对应于用户ISA和系统ISA。因此,两者合起来构成完整的硬件编程接口,即ISA=System ISA+User ISA

(2)OS(Operating System,操作系统)运行于硬件之上,向下管理硬件资源、向上提供系统调用(System Calls)接口。操作系统提供的系统调用(上层应用可以通过系统调用请求操作系统执行特权操作,即执行系统ISA)(1)以及用户ISA共同组成了应用程序的ABI(Application Binary Interface,应用程序二进制接口)。如果两个系统的ABI相同,意味着提供了一个可移植的基础运行环境(2),即ABI=System Calls+User ISA

(3)库程序调用(Library Calls)提供系统运行时(Runtime)、系统公共服务(Services)和功能丰富的第三方程序(如数学库、图形库等),运行于用户态,以函数库的形式供应用程序调用。同时,应用程序一般通过库函数调用操作系统的系统调用接口。因此,对于应用程序而言,底层的系统ISA和操作系统的系统调用是透明的,它主要关心运行环境(包括运行时、服务和库等)提供的API(Application Program Interface,应用程序编程接口)(3)。也就是说,确定了应用程序所使用的用户ISA和所调用的库函数(包括动态库和静态库),也就确定了应用程序的用户态编程接口,即API=Library Calls+User ISA

因此,如图1-2所示,硬件和软件资源在不同层次的抽象对应不同的虚拟化方法。

图1-2 不同层次的虚拟化抽象

(1)物理硬件层的虚拟化:虚拟机监控器Hypervisor通过直接对硬件资源进行抽象和模拟,提供了虚拟硬件ISA(Virtual ISA)接口,包括虚拟系统ISA(Virtual System ISA)和虚拟用户ISA(Virtual User ISA),即Virtual ISA=Virtual System ISA+Virtual User ISA。Hypervisor有时也称为VMM(Virtual Machine Monitor,虚拟机监控器),除非专门列出(例如Rust-VMM是用Rust语言编写的用户态虚拟机监控程序),本书统一采用Hypervisor表述VMM。由于虚拟化技术的多样性,操作系统还可以进一步细分为宿主机操作系统(Host OS)和客户机操作系统(Guest OS),这将在1.3节详细介绍。虚拟硬件ISA提供了完整的硬件资源抽象,从而使多个操作系统能够运行其上并共享硬件资源,例如VMware虚拟化产品VMware Workstation可以在Windows系统上运行一个Linux操作系统。

(2)操作系统层的虚拟化:操作系统本身就是虚拟化技术的一种体现,它将CPU、内存和I/O等资源进行了抽象,最终以进程为单位使用这些资源,并进一步由命名空间(Namespace)和控制组(Cgroups)等容器(Container)技术实现对资源的隔离和限制。因此这一层次的虚拟化也称为轻量级虚拟化、进程虚拟化。有些文献把基于二进制翻译的方法运行相同或不同ISA的二进制程序称为进程虚拟化,例如在基于x86的Windows系统上运行ARM架构的程序。本书采用的术语容器虚拟化主要指基于同构指令集的轻量级虚拟化方法,它提供了虚拟ABI(Virtual ABI)接口,即Virtual ABI=虚拟系统调用Virtual System Calls+Virtual User ISA。近年比较流行的Docker技术便属于容器虚拟化方法。

(3)应用层程序运行环境的虚拟化:应用程序本身作为虚拟机(也称为沙箱,Sandbox),提供用户态虚拟运行时(Virtual Runtime)支撑应用程序的运行,即虚拟API接口=虚拟库程序调用Virtual Library Calls+Virtual User ISA。比较常见的是高级编程语言的虚拟运行环境,例如Java虚拟机和Python虚拟机。注意,这里的用户态ISA有时采用高级编程语言自定义的字节码(Bytecode)抽象,用于屏蔽各个硬件指令集的差异,能够跨平台运行(最终会将字节码编译到某个具体硬件架构的用户态ISA)。

以上是三种基本的虚拟化抽象方法,根据指令集、操作系统是否同构等不同存在多种变体。例如库函数虚拟化:通过拦截用户态程序的系统调用,随后对调用进行仿真和模拟,能够在同一个硬件指令集上运行不同操作系统的程序。例如,Wine(4)基于Linux等操作系统运行Windows的应用软件(通过提供兼容层将Windows的系统调用转换成与Linux对应的系统调用)。从ABI角度分析Wine,用户ISA同构(均为x86指令集),但系统调用异构(分别为Windows与Linux)。

近年日益流行的轻量级Unikernel(5)是一种定制的库操作系统(Library OS)。Unikernel和应用程序一起编译打包,构成单地址空间的可执行二进制镜像,不再严格区分用户态和内核态。因此,Unikernel可以直接运行在硬件或Hypervisor上,就硬件接口而言,Unikernel的CPU和内存部分仍为(高度简化的)虚拟硬件ISA,而I/O部分则基本使用virtio或其他半虚拟化方案,降低了传统虚拟化方法由于逐层软件抽象而引入的性能开销,提供了轻量、高效的虚拟化抽象。

本书主要介绍系统虚拟化,也就是上述物理硬件层的虚拟化,特指在计算机硬件和操作系统之间引入一个系统软件抽象层,由其实际控制硬件,并向操作系统提供虚拟硬件ISA接口,从而可以同时运行多个“虚拟机”(Virtual Machine)。目前指令集同构的系统虚拟化是主流方法,因此本书着重介绍同构虚拟化方法(6)。此外,容器虚拟化与操作系统和硬件密切相关,也是目前大规模使用的云计算的核心技术,本书将在后续章节简要介绍容器虚拟化方面的内容。应用层程序运行环境的虚拟化涉及与硬件平台无关的字节码和沙箱等技术,限于篇幅,不在本书讨论范围之内。

综上所述,系统虚拟化将物理机器抽象成虚拟机器,其抽象粒度包括CPU、内存和I/O在内的完整机器。从本质上来说,系统虚拟化抽象了硬件指令集架构,向上对操作系统提供了硬件特性的等效抽象。对操作系统而言,运行于虚拟机上与运行于物理机上没有区别,即虚拟机可视为真实物理机的高效并且隔离的复制品(A virtual machine is taken to be an efficient,isolated duplicate of the real machine[1])。因此,系统虚拟化的目标是使虚拟机的功能和性能等与物理机接近,即“功能不缺失、性能不损失”。

此外,根据抽象类型的不同,系统虚拟化可以分为“一虚多”(见图1-3(a))和“多虚一”(见图1-3(b))。早期的系统虚拟化主要研究“一虚多”,即把单物理机抽象成若干虚拟机(如一个物理机可以抽象成10个虚拟机)。之后,跨越数量级的硬件性能提升为“多虚一”架构开辟了道路,即把多物理机抽象成单一虚拟机。

图1-3 “一虚多”和“多虚一”

虚拟化技术通过对物理硬件在数量、功能和效果上进行逻辑化虚拟,能够提供高层次的硬件抽象、硬件仿真、服务器整合(Server Consolidation)、资源按需调配、资源聚合、柔性管理、在线迁移、系统高可用、安全隔离等功能,因此虚拟机也成为当前各类硬件平台上的主要载体。虚拟化能大幅提升资源利用率,因为信息系统是按照最大使用峰值设计的,利用率一般不到20%。采用虚拟化技术可以整合资源、削峰填谷和节能降耗,例如电信业信息系统虚拟化后,利用率能够提升到70%以上。根据VMware的报告,VMware vSphere可实现10∶1(10台虚拟机运行于1台物理机之上)或更高的整合率,将硬件利用率从5%~15%提高到80%以上。另外一个典型案例是,2007年《纽约时报》想把从1851年创刊开始到1922年的文章上传到网络,以供免费阅读和搜索,原预计费时数月及花费上百万美元,但租用亚马逊虚拟机,在24小时内将1851—1922年1100万篇文章的报纸扫描件整理成PDF,仅花费240美元。

综上所述,系统虚拟化是把物理硬件资源通过“一虚多/多虚一”抽象成虚拟资源,并使得性能尽可能接近物理资源。同时,与物理资源类似,虚拟资源的四大特性(可靠性、可用性、可维护性和安全性)也是系统虚拟化的重要技术指标,本书在后面的章节中将会逐步对此展开详细介绍。自2009年起,全球新增的虚拟机数量已超过新增的物理机。因此,系统虚拟化技术成为当前支撑云计算、大数据、互联网和机器学习等新型计算和应用模型的核心技术之一。