本篇整理自知乎兰新宇及老秦谈芯公众号等资料整理
1. 虚拟化概念
虚拟化的含义很广泛,将任何一种形式的资源抽象成另一种形式的技术都是虚拟化技术,比如进程的虚拟地址空间,就是把物理内存虚拟成多个内存空间(参考这篇文章)。相对于进程级的虚拟化,虚拟机是另外一个层面的虚拟化,它所抽象的是整个物理机,包括CPU、内存和I/O设备。
在一台物理机上可以模拟出多台虚拟机(Virtual Machine,简称VM),每个虚拟机中都可以运行一个操作系统(OS)。提供虚拟化的平台被称为VMM(Virtual Machine Monitor),在其上运行的虚拟机被称为guest VM(客户机)。根据VMM支持的虚拟机制的不同,guset VM的运行模式可分为完全虚拟化(Full Virtualization)和类虚拟化(Para Virtualization)。
1)完全虚拟化 如果一个基于硬件运行(native)的OS不需要修改任何代码就可以直接跑在VM上,也就是guest OS根本感知不到自己运行在一个虚拟化环境中(可以说VMM是骗术高明的),这种就被称为“完全虚拟化”。在这种模式下,VMM需要正确处理guest所有可能的指令。
最简单直接的方法就是,VMM对guest运行过程中的每一条指令都进行解释和执行,模拟出这条指令执行的效果,这种方法既适用于和VMM相同体系结构的guest,也能用于模拟和VMM不同体系结构的guest(比如物理CPU是x86的,而guest是基于ARM的),其缺点也很明显,就是性能太差。
有一些指令是要操作特权资源的,比如修改虚拟机的运行模式或者下面物理机的状态,读写时钟或者中断寄存器,这些指令被称为敏感指令,确实不适合由guest直接来控制。
然而其他的一些非敏感指令,是完全可以在物理CPU上直接执行并返回结果给guest的,VMM只需要截获并模拟guest对敏感指令的执行和对特权资源的访问就可以了,以intel的VT-x和AMD的AMD-V为代表的硬件辅助虚拟化技术,就可以帮助VMM高效地识别和截获这些敏感指令。
2)类虚拟化 像x86这种CISC架构的系统,指令繁杂,其中一些指令是难以虚拟化的,如果使用完全虚拟化,就需要通过二进制代码翻译(binary translation),扫描并修改guest的二进制代码,将难以虚拟化的指令转换成支持虚拟化的指令(ABI级),就像打补丁一样。
如果能直接修改guest的操作系统内核代码(API级),就可以使得内核避免产生这些难以虚拟化的指令,这就是“类虚拟化”。类虚拟化技术需要修改直接基于native运行的OS代码,以便和VMM更好的配合,其好处就是guest的运行性能可以接近物理机的性能。
2. 主流模型
当前主流的虚拟化技术的实现架构可分为三类:
1)Hypervisor模型 在hypervisor模型中,VMM是一个完备的操作系统,它除了具备传统操作系统的功能,还具备虚拟化功能。包括CPU、内存和I/O设备在内的所有物理资源都归VMM所有,因此VMM不仅要负责虚拟机环境的创建和管理,还承担着管理物理资源的责任。
这种方式是比较高效的,然而I/O设备种类繁多,管理所有设备就意味着大量的驱动开发工作。在实际的产品中,厂商会根据产品定位,有选择的支持一些I/O设备,而不是对所有的I/O设备都提供支持。 2)Host模型(宿主机) 在host模型中,物理资源由host OS管理,host OS是传统操作系统(比如Linux),这些传统操作系统并不是为虚拟化而设计的,因此本身并不具备虚拟化功能,实际的虚拟化功能由VMM来提供。
VMM作为host OS中一个独立的内核模块,通过调用host OS的服务来获得资源,实现CPU、内存和I/O设备的虚拟化。VMM创建出虚拟机之后,通常将虚拟机作为host OS的一个进程参与调度。 Host模型最大的优点就是可以充分利用现有操作系统的设备驱动程序,VMM不需要为各种I/O设备重新实现驱动,可以专注于物理资源的虚拟化;缺点在于,由于VMM是借助host OS的服务来操作硬件,而不是直接操作硬件,因此受限于host OS服务的支持,可能导致硬件利用的不充分。
从架构上看,由Qumranet公司开发的KVM(Kernel-based Virtual Machine)就是属于host模型的,kernel-based,顾名思义就是基于操作系统内核。KVM于2007年被集成到Linux内核2.6.20版本,并于2008年被Red Hat收购。
随着越来越多的虚拟化功能被加入到Linux内核当中,Linux已经越来越像一个hypervisor了,从这个角度看,KVM也可以算是hypervisor模型了。
3)混合模型 在混合模型中,VMM依然位于最底层,拥有所有的物理资源,但为了利用现有操作系统的I/O设备驱动程序,VMM会将大部分的I/O设备交由一个运行在特权级别的虚拟机操作系统(Service OS)来处理,自己则主要负责CPU管理和内存管理。
混合模型可以说是结合了上述两种模型的优点,既不需要另外开发I/O设备驱动程序,又可以通过直接控制CPU和内存实现对这些物理资源的充分利用,以提高效率。
但它也是存在缺点的,当来自guest OS的I/O请求发送到VMM后,VMM需要将这些请求转发到service OS,这无疑增加了上下文的开销。混合模型的代表有Xen,Intel最近推出的Acrn,以及我国工程师写的minos。
上面介绍的这三种VMM实现模型和全虚拟化/类虚拟化的guest VM之间并没有直接的对应关系,比如Xen就既可以支持类虚拟化的guest VM,也可以支持全虚拟化的guest VM。
还有一种划分方法是将VMM分为基于bare-metal的type-1和基于OS的type-2,从这个角度划分的话,hypervisor模型和混合模型都是属于type-1的,host模型则是属于type-2的【1】。
下文将介绍这几种虚拟化技术在x86和ARM平台上的具体实现。
注【1】:这里区分两个名词 - hypervisor和VMM,hypervisor通常仅用于表达type-1的VMM,所以在接下来的《虚拟化技术》系列文章中,除非是仅讨论Xen/Acrn这种确定的type-1的虚拟化平台时,才会使用hypervisor一词,其他时候都统一称为VMM。
开始前,先闲扯一下,最近一个词比较火,“元宇宙(Metaverse)”。在维基百科里面是这么定义元宇宙的,“The Metaverse is a collective virtual shared space, created by the convergence of virtually enhanced physical reality and physically persistent virtual space, including the sum of all virtual worlds, augmented reality, and the Internet”。啥是虚拟呢,通俗点说就是假的,不是物理上真实的。
虚拟化技术是一种广泛使用的技术,比如在云计算业务,数据中心业务中。为什么处理器需要虚拟化,或者说虚拟化能带来什么好处呢?
首先,在处理器设计和应用里,要提一个概念,就是“虚拟机(Virtual Machine)”。关于虚拟机,玩过Vmware的同学可能有一定了解。与虚拟机相对应的就是“真实机(Real Machine)”,有时也叫物理机。物理机好理解,比如我们买一台电脑做家用机,那么这台电脑的所有物理设备,比如硬盘,网卡等等,都是归你自己使用。如果是服务器机,这种独占的使用方式无疑是效率非常低下的。把服务器的巨大资源划分成块分配使用,或者是按照时间片轮流使用,就可以大大提高效率了。这就需要使用到虚拟化技术了。虚拟化技术就是要让应用程序运行在虚拟机上,就像运行在真实机上一样。归纳一下,虚拟化技术能带来的好处有以下几点:
3. 虚拟化优势
1)隔离:即允许在相互不信任的计算环境之间共享物理系统。例如,两个竞争对手可以在一个数据中心共享同一台物理机器,而不能够访问彼此的数据。
2)高可用性:虚拟化技术允许在物理机器之间无缝且透明地迁移工作负载,通常用于将工作负载从可能需要维护和更换的故障硬件平台迁移出去。
3)工作负载平衡:尽可能多地使用每个硬件平台,这可以通过虚拟机的迁移来实现,或者通过在物理机上共同托管适当的工作负载来实现。
4)沙箱:虚拟机可用于为可能干扰其运行的机器其他部分的应用程序提供沙箱。在虚拟机中运行这些应用程序可以防止应用程序的错误或恶意部分干扰物理计算机上的其他应用程序或数据。
当然,虚拟化技术带来的好处不止这些,此处就不一一列举了。
如何把虚拟机和真实的物理设备隔绝呢,或者说如何实现虚拟化。聪明的行业前辈们想到了一个方法,在hardware之上加一层hypervisor。对于hypervisor,百度百科是这样定义的,“一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。也可叫做VMM( Virtual Machine Monitor ),即虚拟机监视器。Hypervisor是一种在虚拟环境中的“元”操作系统。他们可以访问服务器上包括磁盘和内存在内的所有物理设备。Hypervisor不但协调着这些硬件资源的访问,也同时在各个虚拟机之间施加防护。当服务器启动并执行Hypervisor时,它会加载所有虚拟机客户端的操作系统同时会分配给每一台虚拟机适量的内存,CPU,网络和磁盘”。
有了hypervisor,我们再来看一下系统如何构成。先以汽车芯片为例,如下图。Hypervisor负责协调,控制所有的硬件资源。在hypervisor之上,把汽车行驶和安全相关的部分隔离成一部分,运行封闭操作系统(Closed OS);把与娱乐等相关的部分隔离成另一部分,运行开放操作系统(Open OS)。相对应的应用程序(APP)运行在各自操作系统之上。这样就可以起到一个很好的隔离作用,用户自己安装的APP不会影响到汽车行驶安全。
图1 汽车芯片中的虚拟化示意图
再来看一个服务器的例子,如下图。一台服务器可能拥有很多的处理器,硬盘等。通过hypervisor,可以分配给不同的虚拟机以不同的硬件资源。比如对于VM1,可能要运行一些安全等级高的任务,这时就可以把Hardware0的资源只分配给VM1,其它的虚拟机不能访问。对于Hardware1,同时分配给VM0,VM1,VM2等多个虚拟机,充分利用其资源。
图2 服务器芯片中的虚拟化示意图
Hypervisor分为两大类,一类是standalone hypervisor,或者叫type 1;另一类是hosted hypervisor,也叫type 2。 图3 Type 1 hypervisor(standalone) 图4 Type 2 hypervisor(hosted)
两者的区别是: Type 1 的 hypervisor 是直接运行在硬件之上的,而type 2 的 hypervisor 是运行在Host OS之中的。 Type 1 相当于一个轻量级的操作系统,直接跑在宿主机的硬件上; Type 2 相当于一个应用软件,运行在宿主机的操作系统之中。 两者相同的是: 客户操作系统(Guest OS)都是运行在 hypervisor 之上的。Type 1的hypervisor通常在性能上比Type 2表现的更好,更为安全。Type 2相较于type 1还有一个缺点就是延迟太高,这是因为hypervisor与硬件之间的交流还需要穿过操作系统这一层。Hosted hypervisor最多的应用场景是作为client hypervisor运行在终端用户的电脑上,而这种场景下一般是不需要关心延迟问题的。大多数企业一般选择Type 1类型的hypervisor用于数据中心的计算需求。
在ARM平台上,type 1 hypervisor比较典型的代表是Xen。Xen是由剑桥大学计算机实验室开发的一个开源项目。是一个直接运行在计算机硬件之上的用以替代操作系统的软件层,它能够在计算机硬件上并发的运行多个Guest OS。Xen支持x86、x86-64、Power PC和ARM多种处理器。2014年03月11日,Xen发布4.4版本,更好地支持ARM架构。
Xen是半虚拟化(Para-Virtualization)技术的典型代表。半虚拟化技术,主要解决的就是如何捕获非特权指令的敏感指令。
x86体系是导致半虚拟化技术产生的重要原因,因为x86体系结构中,部分敏感指令不是特权指令,这些指令不能自动产生异常,因此想要系统正常运行就必须要捕获这些指令。于是Xen采用修改Guest OS内核的方法对这些有缺陷的指令进行替换。根据直觉,既然有半虚拟化,就一定有全虚拟化,对不对?没错,你很机智,确实有“完全虚拟化”,又称“硬件虚拟化(Hardware Virtual Machine)”。简单说,两者的区别就是在半虚拟化中,Guest OS知道自己运行在Hypervisor上而不是硬件上,同时也可以识别出其他运行在相同环境中的客户虚拟机。在全虚拟化中,Guest OS任务自己运行在硬件上,无法感知其他Guest OS。
在ARM平台上,type 2 hypervisor比较典型的代表是KVM。
**KVM(Kernel-basedVirtual Machine)**是一个基于Linux环境的开源虚拟化解决方案,最早由以色列Qumranet公司开发,并于2007年2月被集成到 Linux 2.6.20内核中,成为内核的一部分。与 VMware ESX/ESXi、微软 Hyper-V 和Xen 等虚拟化产品不同,KVM 的思想是在Linux内核的基础上添加虚拟机管理模块,重用Linux内核中已经完善的进程调度、内存管理、IO管理等代码,使之成为一个可以支持运行虚拟机的 Hypervisor。 图5 Xen和KVM对比示意图
|