购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2 IaaS关键实现技术之服务器虚拟化

服务器虚拟化技术是指能够在一台物理服务器上运行多台虚拟服务器的技术,并且上述虚拟服务器在用户、应用软件甚至操作系统看来,几乎与物理服务器没有区别,用户可以在虚拟服务器上灵活地安装任何软件。除此以外,服务器虚拟化技术还应该确保上述多个虚拟服务器之间的数据是隔离的,虚拟服务器对资源的占用是可控的。

3.2.1 服务器虚拟化概述

在服务器虚拟化技术中,被虚拟出来的服务器称为虚拟机(Virtual Machine,VM)。运行在虚拟机里的操作系统称为客户操作系统,即Guest OS。负责管理虚拟机的软件称为虚拟机管理器,缩写为VMM,也称为Hypervisor。

服务器虚拟化通常有两种架构,分别是寄生架构(Hosted)与裸金属架构(Bare-metal)。

(1)寄生架构。

一般而言,在使用计算机之前,首先要安装操作系统,该操作系统称为宿主操作系统,即Host OS。如果采用虚拟机技术,则需要在操作系统之上再安装一个VMM,然后利用这个VMM创建并管理虚拟机。这种后装模式称为寄生架构,因为VMM看起来像是“寄生”在操作系统上的。例如,Oracle公司的VirtualBox就是一种寄生架构。

(2)裸金属架构。

顾名思义,裸金属架构是指将VMM直接安装在物理服务器之上而无须先安装操作系统的预装模式。在安装了VMM之后,再在VMM上安装其他操作系统(如Windows、Linux等)。由于VMM“看起来”是直接安装在物理计算机上的,所以称为裸金属架构,例如KVM、Xen、VMware ESX。

目前,普遍认为裸金属架构的性能要比寄生架构高。很多资料都宣传说,裸金属架构是直接运行在物理硬件之上的,无须通过Host OS,所以性能更高。

图3-1为Xen的工作流程,其中有3个Domain。一开始,很多人会将Domain误认为是CPU的一种特殊状态,这是因为在很多文档里会用一些比较模糊的措辞,例如“此时,系统会进入Domain0状态”,从而让人产生误解。其实,Domain在虚拟化技术里表示的不是CPU的状态,而是“域”,更通俗地说,就是一台虚拟机。

虽然从图3-1上看,Xen是运行在硬件之上的,但实际上,Xen严重依赖于一个特殊的Domain,那就是Domain0。其实,Xen在发布其裸金属版本的时候,里面就包含了一个裁剪过的Linux内核,它为Xen提供了除CPU调度和内存管理之外的所有功能,包括硬件驱动、I/O、网络协议、文件系统、进程通信等所有其他操作系统所做的事情。这个Linux内核就运行在Domain0 里面。这就是为什么当启动裸金属架构版的Xen时会自动启动Domain0。因为没有这个Linux内核,Xen将无法工作。事实上,基于裸金属架构的VMM中往往包含了一个经过修改的Host OS。

图3-1 Xen的工作流程

因此,裸金属架构其实并不说明VMM能够抛开Host OS在硬件之上运行。如果我们把图3-1中的Domain0放到与Xen Hypervisor平级的位置,或者放到Xen Hypervisor下面,Domain0就与寄生架构没有区别了,如图3-2所示。而事实上,即使是寄生架构的产品,例如VirtualBox,在Host OS里面也会有一个运行于核心的驱动程序,它可以直接与物理设备打交道。

如果仔细看图3-2,会发现Domain1和Domain2与Domain0之间还有一些通信。这与传统的寄生架构一样,Guest OS有时也是需要访问Host OS的。所以,裸金属架构本身不会给Guest OS的性能带来任何提升。

从目前的趋势来看,虚拟化将成为操作系统本身功能的一部分。例如,KVM就是Linux标准内核的一个模块,微软的Windows 2008也自带Hyper-V。

图3-2 寄生架构

下面将重点介绍服务器关键部件的虚拟化方法,包括CPU、内存、I/O的虚拟化。关于网卡的虚拟化方法详见第3.4节。

3.2.2 CPU虚拟化

CPU虚拟化是指将单个物理CPU虚拟成多个虚拟CPU供虚拟机使用。虚拟CPU分时复用物理CPU,虚拟机管理器负责为虚拟CPU分配时间片,并同时对虚拟CPU的状态进行管理。

在x86指令集中,CPU有0~3共4个特权级(ring)。其中,第0级具有最高的特权,用于运行操作系统;第3级具有最低的特权,用于运行用户程序;第1级和第2级很少使用。在对x86服务器实施虚拟化时,VMM通常需要最高的特权级,从而占据第0级;而虚拟机中安装的Guest OS只能运行在更低的特权级中,因此它就不能执行那些只能在第0级执行的特权指令了。为了解决这一问题,在实施服务器虚拟化时,必须要对相关CPU特权指令的执行进行虚拟化处理,以消除虚拟化对Guest OS的运行造成的影响。

CPU特权指令的虚拟化有模拟执行和操作系统辅助两种方法,随着CPU硬件对虚拟化技术的支持,虚拟机中的操作系统基于硬件辅助的虚拟化技术正成为当前CPU虚拟化的主要趋势。

1.基于模拟执行的CPU虚拟化

在Guest OS的运行过程中,当它需要执行在第0级才能执行的特权指令时,会陷入运行在第0级的VMM中。VMM捕捉到这一指令后,将相应指令的执行过程用本地物理CPU指令集中的指令进行模拟,并将执行结果返回Guest OS,从而实现Guest OS在非第0级环境下对特权指令的执行。

CPU特权指令的模拟执行可以有多种方法,不同的方法具有不同的计算开销、实现性能及可移植性,典型的方法是解释执行和二进制翻译。解释执行的过程是:首先获得一条源指令,并对其所需的各个操作内容进行分析,然后执行相应的操作,待执行完成后,再取得下一条源指令,并按照前面的过程执行,这些步骤完全由软件完成。而二进制翻译则不同:它将一段源指令直接翻译成将被执行的目标指令,并将其保存,供重复使用,而不需要在指令执行过程中反复执行取指令和分析指令等过程。两种方法相比较,二进制翻译在初始时需要较高的开销用于指令翻译,但是在执行过程中的开销却得到了有效的降低。具体哪种方法更为适用,则要根据实际的指令执行情况进行选择。例如,如果程序中对同一指令段进行多次执行,那么二进制翻译将具有更高的性能。

基于模拟执行的CPU虚拟化特别适用于那些虚拟化CPU与本地物理CPU的指令集不同的应用场合。而对基于x86 CPU的服务器虚拟化来说,尽管虚拟机指令集与物理机指令集是相同的(x86指令集),但是Guest OS对特权指令的执行仍旧只能通过首先陷入VMM中,再由VMM在物理机上执行同一指令的方法来模拟。基于模拟执行的CPU虚拟化对特权指令的模拟执行需要较高的性能开销。早期的VMware采用的就是基于模拟执行的CPU虚拟化技术。

2.基于操作系统辅助的CPU虚拟化

基于操作系统辅助的CPU虚拟化不需要在程序运行过程中陷入VMM中进行相关的处理和操作,它直接对Guest OS进行修改,将其与特权指令执行相关的操作调用以Hypercall的形式改写。Hypercall类似于系统调用,但它不是针对操作系统进行操作的,而是用于直接和VMM通信,并在其管理下执行特权指令。

基于模拟执行的CPU虚拟化为Guest OS的运行提供了与物理CPU完全一致的硬件环境,是完全的虚拟化。而基于操作系统辅助的CPU虚拟化则不同,它提供了与真实的物理设备有一定差异的CPU指令集接口,然后通过改写Guest OS调用该接口,使Guest OS的相关操作都可以在底层硬件上直接实现,而无须额外的VMM模拟执行。因此,它的最大优势是能够有效地使Guest OS的运行获得与其在本地物理CPU上直接执行相接近的性能。但是,基于操作系统辅助的CPU虚拟化存在的最大问题在于它需要对Guest OS进行改动,这使它只可能对有限的开源操作系统提供支持,而无法支持更多非开源的商业操作系统(例如微软的Windows系列操作系统)。另外,即使是修改开源的Guest OS,也将是一项耗费人力、物力并且存在一定安全性和可靠性风险的事情,而且修改后的操作系统将只能与特定的VMM绑定,可移植性较差。

理论上,基于操作系统辅助的CPU虚拟化可以通过Hypercall的不同设计来实现(例如在VMM上实现Hypercall时采用相应的指令模拟执行的方法),为 Guest OS提供与底层物理CPU不一致的硬件环境,但这需要高昂的Hypercall开发代价和执行性能开销。因此,当前该类虚拟化方法还是普遍用于为Guest OS提供与底层物理CPU一致的硬件环境。早期的Xen采用的就是基于操作系统辅助的CPU虚拟化技术。

3.基于硬件辅助的CPU虚拟化

传统的x86 CPU不能有效地支持虚拟化,使相关的CPU虚拟化技术只能考虑采用软件层面的方法,从而导致了执行性能低或代码开发上的额外开销。随着硬件技术的发展,当前主流的x86 CPU开始在硬件层面上提供对虚拟化的支持,因此,基于硬件辅助的CPU虚拟化逐渐引起了人们的重视。

目前,x86 CPU的硬件辅助虚拟化技术主要包括Intel VT-x和AMD SVM,两者在实现的原理上具有相同之处。以Intel VT-x为例,它为x86 CPU增加了一个名为“VMX”的处理模式。在VMX模式下有两种状态,分别是“VMX root operation”和“VMX non-root operation”。其中,VMX root operation状态专为VMM的运行而设,它的行为和传统的不包含VT-x技术的x86 CPU相同;而VMX non-root operation状态则提供了一个在VMM控制之下的用于支撑虚拟机运行的CPU环境。无论是VMX root operation状态还是VMX non-root operation状态,都支持4个特权级,这就允许虚拟机中的Guest软件能够继续在从前的特权级上执行,同时也为VMM今后的发展提供了多个特权级的支持。在VT-x中,从VMX non-root operation状态到VMX root operation状态的转换称作“VM entry”,反之则称作“VM exit”。与VMX处理模式相对应,VT-x增加了一组专用的VMX指令。

在VT-x的应用过程中,CPU首先以正常处理模式启动,然后通过执行vmxon指令,使CPU进入VMX模式,并由VMM执行VMX root operation。这时,VMM可以为虚拟机设置环境并通过执行vmlaunch指令启动虚拟机。一旦启动虚拟机,CPU就将由虚拟机执行VMX non-root operation。在虚拟机执行过程中,如果需要进行一些与虚拟机管理相关的操作(例如资源的重新配置),那么虚拟机会将CPU的控制权让给VMM,通过执行vmcall指令使CPU重新进入VMX root operation状态。当VMM完成相关的管理操作后,会通过执行vmresume指令重新唤起虚拟机,并将CPU置于VMX non-root operation状态。因此,在一般情况下,CPU大部分时间都工作在VMX non-root operation状态下。当CPU希望退出VMX模式时,它通过执行vmxoff指令使所有的虚拟机依次关机,并返回正常模式。

基于硬件辅助的CPU虚拟化弥补了之前x86 CPU不能被有效虚拟化的缺陷。使用这类虚拟化技术,VMM位于比第0级更高的特权级中,且不会影响Guest OS对特权指令的执行。因此,它有效地避免了特权指令模拟执行产生的性能开销,也消除了操作系统虚拟化所需的对Guest OS的改写。但是,使用基于硬件辅助CPU虚拟化的主要问题在于,工作在VMX模式下的CPU在进行VMX root operation状态和VMX non-root operation状态的切换时,VM entry和VM exit过程需要消耗大量的CPU周期,成为性能的瓶颈。因此,当前的硬件虚拟化技术正在极力改善这一问题,主要是从减少每次切换的消耗周期数和切换的发生次数等方面入手。另外,不同厂商的硬件虚拟化技术尚缺乏统一的标准,这也是业界亟待解决的问题之一。

现在,主流的虚拟化产品都已经转型到基于硬件辅助的CPU虚拟化。例如,KVM在一开始就要求CPU必须支持虚拟化技术。此外,VMware、Xen、Hyper-V等都已经支持基于硬件辅助的CPU虚拟化技术了。

3.2.3 内存虚拟化

内存虚拟化是指VMM通过维护物理机内存和虚拟机所见到的“物理内存”的映射关系,为虚拟机分配物理机的内存,使虚拟机看到的内存为从地址0开始的连续物理地址。

为实现内存虚拟化,内存系统中共有3种地址。

◎ 机器地址(Machine A ddress,MA):真实硬件的机器地址,在地址总线上可以见到的地址信号。

◎ 虚拟机物理地址(Guest Physical Address,GPA):经过VMM抽象后虚拟机看到的伪物理地址。

◎ 虚拟地址(Virtual A ddress,VA):Guest O S为其应用程序提供的线性地址空间。

虚拟地址到虚拟机物理地址的映射关系记作g,由Guest OS负责维护。对于Guest OS而言,它并不知道自己所看到的物理地址其实是虚拟的物理地址。虚拟机物理地址到机器地址的映射关系记作f,由VMM的内存模块进行维护。

普通的内存管理单元(Memory Management Unit,MMU)只能完成1次虚拟地址到物理地址的映射,但获得的物理地址只是虚拟机物理地址,而不是机器地址,所以需要通过VMM来获得总线上可以使用的机器地址。但是如果每次内存访问操作都需要VMM的参与,效率将变得极低。为实现虚拟地址到机器地址的高效转换,目前普遍采用的方法是:由VMM根据映射f和g生成复合映射f·g,直接写入MMU。具体的实现方法有两种。

(1)MMU半虚拟化(MMU Paravirtualization)。

这种方式主要为Xen所用,其主要原理是:当Guest OS创建新页表时,VMM从维护的空闲内存中分配页面并进行注册,以后Guest OS对该页表的写操作都会陷入VMM中进行验证和转换;VMM检查页表中的每一项,确保它们只映射属于该虚拟机的机器页面,而且不包含对页表页面的可写映射;然后,VMM会根据其维护的映射关系f将页表项中的物理地址替换为相应的机器地址;最后,再把修改过的页表载入MMU,MMU就可以根据修改过的页表直接完成从虚拟地址到机器地址的转换了。这种方式的本质是将映射关系f·g直接写入Guest OS的页表中,替换原来的映射g。

(2)影子页表。

全虚拟化使用影子页表技术实现内存虚拟化。影子页表与MMU半虚拟化的不同之处在于:VMM为Guest OS的每一个页表维护一个影子页表,并将f·g映射写入影子页表中,Guest OS的页表内容保持不变。最后,VMM将影子页表写入MMU。

影子页表的维护将带来时间和空间上的较大开销。时间开销主要体现在由于Guest OS构造页表时不会主动通知VMM,VMM 必须等到Guest OS发生缺页时才通过分析缺页原因为其补全影子页表。而空间的开销主要体现在VMM需要支持多台虚拟机同时运行,每台虚拟机的Guest OS通常会为其上运行的每一个进程创建一套页表系统,因此影子页表的空间开销会随着进程数量的增多而迅速增大。

为权衡时间开销和空间开销,现在一般采用影子页表缓存(Shadow Page Table Cache)技术,即VMM在内存中维护部分最近使用过的影子页表,只有当缓存中找不到影子页表时,才构建一个新的影子页表。当前主要的全虚拟化技术都采用了影子页表缓存技术。

3.2.4 I/O虚拟化

I/O虚拟化就是通过截获Guest OS对I/O设备的访问请求,用软件模拟真实的硬件,复用有限的外设资源。I/O虚拟化与CPU虚拟化是紧密相关的。例如,当CPU支持硬件辅助虚拟化技术时,往往在I/O方面也会采用Direct I/O等技术,使CPU能直接访问外设,以提高I/O性能。当前I/O虚拟化的典型方法如下。

(1)全虚拟化。

VMM对网卡、磁盘等关键设备进行模拟,以组成一组统一的虚拟I/O设备。Guest OS对虚拟设备的I/O操作都会陷入VMM中,由VMM对I/O指令进行解析并映射到实际物理设备,直接控制硬件完成操作。这种方法可以获得较高的性能,而且对Guest OS是完全透明的。但VMM的设计复杂,难以应对设备的快速更新。

(2)半虚拟化。

半虚拟化又叫做前端/后端模拟。这种方法在Guest OS中需要为虚拟I/O设备安装特殊的驱动程序,即前端(Front-end Driver)。VMM中提供了简化的驱动程序,即后端(Back-end Driver)。前端驱动将来自其他模块的请求通过VMM定义的系统调用与后端驱动通信,后端驱动收到处理请求后会检查请求的有效性,并将其映射到实际物理设备,最后由设备驱动程序来控制硬件完成操作,硬件设备完成操作后再将通知发回前端。这种方法简化了VMM的设计,但需要在Guest OS中安装驱动程序甚至修改代码。

基于半虚拟化的I/O虚拟化技术往往与基于操作系统的辅助CPU虚拟化技术相伴随,它们都是通过修改Guest OS来实现的。

(3)软件模拟。

软件模拟即用软件模拟的方法来虚拟I/O设备,指Guest OS的I/O操作被VMM捕获并转交给Host OS的用户态进程,通过系统调用来模拟设备的行为。这种方法没有额外的硬件开销,可以重用现有驱动程序。但是完成一次操作需要涉及多个寄存器的操作,使VMM要截获每个寄存器访问并进行相应的模拟,导致多次上下文切换。而且由于要进行模拟,所以性能较低。

一般来说,如果在I/O方面采用基于软件模拟的虚拟化技术,其CPU虚拟化技术也应采用基于模拟执行的CPU虚拟化技术。

(4)直接划分。

直接划分指将物理I/O设备分配给指定的虚拟机,让Guest OS可以在不经过VMM或特权域介入的情况下直接访问I/O设备。目前与此相关的技术有Intel的VT-d、AMD的IOMMU及PCI-SIG的IOV。这种方法重用已有驱动,直接访问也减少了虚拟化开销,但需要购买较多的额外硬件。该技术与基于硬件辅助的CPU虚拟化技术相对应。VMM支持基于硬件辅助的 CPU 虚拟化技术,往往会尽量采用直接划分的方式来处理I/O。 DWK9UghHn+I+5SzVLXiiReI+UaqcewxMr89O2fVBtUQxgdbdp6/NyIVYAvwvsQPR

点击中间区域
呼出菜单
上一章
目录
下一章
×