十年前,“云” 的话题才刚刚出现,当时的重点是公共基础架构中的简单服务。但正如技术中的典型情形那样,这些服务随着其使用模式不断发展。同样地,在商用硬件上引入虚拟化也只是为了关注最简单的使用模式,然后,随着人们越来越认可虚拟化潜能,虚拟化也在不断发生演变。
因为硬件提供者目睹了虚拟化和云的发展,所以他们也将提供的产品发展成为能够更有效地满足需求。早先的 x86 处理器对虚拟化并不理想,但一些处理器内行人士则一直关注于新的使用模式,并为平台虚拟化创建了一种更有效的环境。
让我们先来简短介绍一下云架构及其具有的一些限制。
公有云架构
公有云(或可公开使用的虚拟化基础架构)侧重的是虚拟服务器的简单分配,该分配是通过多租户使用的虚拟机管理程序完成的。虚拟机管理程序充当的是一个多路复用器 (multiplexer),让一个物理平台可供多个用户共享。有多个产品可供虚拟机管理程序(从 Kernel 虚拟机 (KVM) 到 Xen 虚拟机管理程序等)使用。
在虚拟化了的基础架构中存在一个限制,即虚拟化对给定虚拟环境的依赖性。比如,Amazon Elastic Compute Cloud (Amazon EC2) 依赖于 Xen 虚拟化。Amazon EC2 希望运行在其基础架构中的所有来宾都能够以一种称为 Amazon Machine Image (AMI) 格式的特定方式进行打包。AMI 是 Amazon EC2 内的基础部署单元,可以是诸多预配置类型(基于操作系统和应用程序集)中的一种,也可以通过某些额外工作进行定制创建。
这种虚拟机 (VM) 格式(包括元数据和一种虚拟的磁盘格式)有可能成为云使用者的一个障碍。将 VM 从私有的基础架构迁移到公共基础架构或在公共基础架构之间相互迁移的能力会受到这种格式的阻碍,而且会过多地依赖于目标虚拟机管理程序的选择。
因此,对于嵌套虚拟化的支持将会为云使用者创建新的抽象。如果云支持在一个虚拟机管理程序上虚拟化另一个虚拟机管理程序,那么 VM 格式就会与云无关。惟一的依赖关系是此来宾虚拟机管理程序本身的格式。这种改变将第一代云从一成不变演变成了高度灵活的虚拟化基础架构,为用户带来了更多的自由。图 1 展示了面向虚拟机管理程序的虚拟平台上下文环境中的新抽象,不仅仅是 VM。请注意此图中对虚拟化的不同级别所使用的术语:L0 代表的是裸机虚拟机管理程序,L1 代表的是来宾虚拟管理程序,L2 代表的是来宾 VM。
图 1. 传统虚拟机管理程序对比嵌套虚拟机管理程序的简单说明
这种改变带来的功能不仅包括为新的基础架构打包 VM,还包括打包 VM 集与其虚拟机管理程序,简化了私有云基础架构用户将功能(静态或动态)迁移到公有云基础架构的过程。这种改变如 图 2 所示,包含将私有虚拟机管理程序转换成嵌套云中的来宾虚拟机管理程序的转换。
图 2. 嵌套云中的来宾虚拟机管理程序和主机虚拟机管理程序
下一代云:引入了嵌套虚拟化
嵌套虚拟化并不是一个新概念,这个概念在 IBM? z/VM? 虚拟机管理程序中已经实现有一段时间了。IBM System z? 操作系统本身就是一个虚拟机管理程序,它不仅虚拟化了处理器和内存,还虚拟化了存储器、网络硬件协助和其他资源。z/VM 虚拟化管理程序代表的是有硬件协助的实际嵌套虚拟化的首次实现(为性能)。此外,z/VM 虚拟机管理程序还支持任何深度的 VM 嵌套(当然,有额外的费用)。新近,基于该技术使用模式的增加,x86 平台已经开始向虚拟化协助进军。
实现嵌套虚拟化,并用于商用硬件的第一个虚拟机管理程序是 KVM。增加对 KVM 的支持是在 IBM 的 Turtles 项目下执行的,并允许多个未修改的虚拟机管理程序在 KVM 之上运行(本身就是一个虚拟机管理程序,可充当 Linux? 内核的一个自制系统优化工具)。启动 Turtles 项目的部分原因是:客户想采用 IBM 倡导的使用 IBM System p? 和 System z 操作系统的方式来使用商用硬件。在这种模型中,服务器运行了一个嵌套式虚拟机管理程序,并允许用户在其上运行其自选的虚拟机管理程序。这种方式吸引了虚拟化社区,因为有些功能(对 KVM 的修改)目前已经成为主流 Linux 内核的一部分。
嵌套虚拟化的架构
嵌套虚拟化带来了一些前所未见的独特问题。让我们一同来看看这些问题,了解如何在 KVM 中解决它们。
处理器虚拟化
目前的处理器架构中的虚拟化支持所存在的一个缺陷是它侧重双级(dual-level)虚拟化(单个虚拟机管理程序上堆叠多个 VM)。Turtles 通过简单的多路复用处理扩展了这一支持。回顾 图 1 可以看出,存在三个级别(L0 为主机虚拟机管理程序,L1 为来宾虚拟机管理程序,L2 为来宾 VM)。利用当今的处理器,可有效处理 L0 和 L1,但无法有效处理 L2。Turtles 并未维护这种严格的堆叠,而是复用了 L1 上的各个条目( entities),并实际允许主机虚拟机管理程序在 L1 上复用来宾虚拟机管理程序和来宾 VM。因此,没有通过虚拟化这些虚拟化指令来支持这三层,而是有效使用了处理器中的可用硬件协助来支持这三层(参见 图 3)。
图 3. 复用主机 (L0) 虚拟机管理程序上的来宾
但是,利用处理器的虚拟化资产并不是惟一的障碍。让我们来看看其他的一些问题,以及它们在 KVM 中的解决方案。
嵌套虚拟化带来了一些有趣问题。请注意,传统的虚拟化部分处理了指令集,直接执行处理器上的某些指令,并通过陷阱模仿其他指令。在嵌套虚拟化中,引入了另一个级别,在这一级别上,某些指令继续直接在硬件上执行,而其他指令则被捕获并托管在一层或其他层中(具有用于各层之间的转换的有效负载)。
这种设置会公开处理器虚拟化实现中的优势和劣势,正如 Turtles 项目发现的那样。VM 控制结构 (VMCS) 的管理就是这样的一个领域。在 Intel 的实现中,读写这些结构涉及到一些特权指令,要求跨嵌套堆栈的各层进行多次出入。这些转换会带来有效负载,以性能降低的形式表现出来。AMD 的实现则通过正常的内存读写来管理 VMCS,这意味着当来宾虚拟机管理程序 (L1) 修改了来宾 VM 的 VMCS (L2) 时,并不要求主机虚拟机管理程序 (L0) 的介入。
即使没有处理器对嵌套的支持,Turtles 复用方法仍会最大程度地减少各层之间的转换。虚拟化中的转换通过出入 VM 的特殊指令(VMexit 和 VMentry)进行,并且代价昂贵。某些退出指令还会要求 L1 虚拟机管理程序的介入,但其他的条件(比如外部中断)则由 L0 独自处理。最大程度地减少 L2 到 L0 到 L1 的转换,这会导致性能提升。
MMU 和内存虚拟化
在借助现代处理器中的页表协助之前,虚拟机管理程序会模仿内存管理单元 (MMU) 的行为。来宾 VM 会创建来宾页表来支持来宾虚拟地址到来宾实际地址的转换。虚拟机管理程序维护了一些影子页表,以便将来宾物理地址转换为主机物理地址。这会要求捕获页表的变化,以便虚拟机管理程序能够管理 CPU 中的物理表。
Intel 和 AMD 都通过添加二维页表来解决这个问题,Intel 称之为扩展页表 (EPT),AMD 称之为嵌套页表 (NPT)。这些协助允许二级页表将来宾物理地址转变为主机物理地址(而传统页表则继续支持来宾虚拟到来宾物理的转换)。
Turtles 项目引入了三个模型来处理嵌套。首要的也是最无效的地方是在影子页表上使用影子页表。如果来宾和主机虚拟机管理程序维护了影子表,那么这个做法仅在硬件协助均不可用的时候使用。第二个方法是在 L0 管理的二维页表之上使用影子表。虽然有效性更好一些,但是来宾 VM 内的页错误会导致多个 L1 退出并带来有效负载。最后一种方法是为 L1 虚拟机管理程序虚拟化这个二维页表。通过在 L1 上仿真这个二级页表(L0 使用的是物理 EPT/NPT),L1 退出次数和带来的有效负载都会减少。来自 Turtles 项目的这种创新形式被称为多维分页。
I/O 设备虚拟化
虚拟化 I/O 设备可能是虚拟化代价最为昂贵的方面之一。仿真(由 QEMU 提供)最为昂贵,像半虚拟化(让来宾了解并用虚拟机管理程序协调 I/O)这样的方式能够提升总体性能。最有效的方案是使用像 AMD I/O MMU (IOMMU) 这样的硬件协助来提供来宾物理地址到主机物理地址的透明转换(用于直接内存访问 [DMA] 这样的操作)。
Turtles 项目通过赋予 L2 来宾对 L0 的可用物理设备的直接访问来提高性能。L0 主机虚拟机管理程序为 L1 来宾虚拟机管理程序仿真了一个 IOMMU。这种方法最大程度地减少了来宾退出(exit),从而减少了有效负载,提升了性能。
嵌套的性能
根据使用的模型,KVM 中的嵌套可能导致的有效负载可以忽略不计。促使 VM 退出的工作负载(比如外部中断处理)常常是最坏的冒犯者,但 KVM 内的优化则会带来 6% 到 14% 的负载提升。考虑到嵌套虚拟化所提供的功能,这个有效负载当然还是合理的。处理器架构的进步将会进一步改善这一点。#p#
何处可以找到嵌套虚拟化?
如今,大量虚拟机管理程序均支持嵌套虚拟化,但还不是很高效。Linux KVM 支持最新的启用了虚拟化功能的处理器上的嵌套。Xen 虚拟机管理程序也已做了相应修改,以支持嵌套的虚拟化,所以开源社区已经快速转而采用这一功能及其潜在的使用模式。
从产品的立场上衡量,这个功能尚处于早期的开发阶段。此外,利用嵌套扩展虚拟化意味着物理主机上的负载的加重,因此应该采用处理器功能更强的服务器。
还要注意的是,在其他的上下文环境中执行嵌套虚拟化也是可行的。在最新的一篇 OpenStack 文章中,通过使用 VirtualBox 作为主机虚拟机管理程序并使用 QEMU(提供仿真)作为来宾来展示嵌套。虽然这不是最为高效的配置,但这篇文章介绍了更为普遍的硬件上的一些基本功能。有关的更多细节,请参阅 参考资料。
其他应用程序
未来,使用虚拟机管理程序作为桌面机或服务器上的固件中的标准组成部分可能会非常常见。这种使用模式意味着嵌套的虚拟机管理程序可以支持一个操作系统(作为 VM)或用户自选的另一个虚拟机管理程序。
以这种方式使用虚拟机管理程序还可以支持新的安全模型(因为虚拟机管理程序存在于用户的代码和黑客的代码之下)。此概念最初用于不法的目的。"Blue Pill" rootkit 是 Joanna Rutkowska 的开发结果,它会在操作系统的一个运行实例下插入一个瘦虚拟机管理程序。Rutkowska 还开发了一个称为 Red Pill 的技术,可用来检测将 "Blue Pill" 插入运行的操作系统之下的时间。
结束语
通过使用 KVM 虚拟机管理程序作为测试平台,Turtles 项目证明了虚拟机管理程序的嵌套虚拟化不仅是可能的,而且在某些情况下还很高效。KVM 方面的研究工作还在继续,但它现在已经成为在虚拟机管理程序中实现嵌套的一个模型,支持多个来宾虚拟机管理程序的同时执行。随着处理器架构逐渐能够满足这些新需求,未来,嵌套虚拟化很可能会成为一个常见的使用模式,不仅会出现在下一代云产品的企业服务器中,还会出现在商用服务器和台式机上。