在 Linus 明确表示 Linux Kernel 3.0 只是一个版本号的改变,而非里程碑式的飞跃后,许多人对此表达了失望,一个没有重量级功能的新版本似乎配不上这个新的版本号。不过对有些人来说,其中的一个新功能或许可以担的上这个重任,那就是 Xen 的 block backend driver。这个功能加上之前在 2.6.37,2.6.38,2.6.39 添加的几个 Xen 相关的功能,使得即将发布的 Kernel 3.0 包含了所有成为 Xen 的 Domain0 所必须的功能,从此为 Xen 漫长的 Kernel 之路划上了一个句号,也标志着 Xen 的发展掀开了崭新的一页。
 
VMWare,Binary Translation 以及 Full Virtualization
 
    提起虚拟化,一个不得不提的公司或者产品是 VMWare,如果说虚拟化最早的原型可以追溯到上世纪 70 年代的 IBM 的 VM 的话,那么当前的虚拟化热潮却是由 VMWare 引领的。相信有很多人跟我一样,对虚拟化的认知是通过 VMWare 得到的。当我初次接触 VMWare 时,我非常惊讶,居然有这样的产品实现了这么 nice 的功能。VMWare 的成功除了契合了时代的变迁所催生出的虚拟化需求外,也得益于自身产品的优秀。VMWare 产品的简单,便捷,易于理解当然是其中非常重要的一个优势,但更重要的原因来自于 VMWare 创造性的解决了 x86 平台内在不支持虚拟化的难题。
 
    x86 平台难以虚拟化的本质主要来自于 CPU 的虚拟化。众所周知,x86 处理器的指令有 4 个特权等级,分别是 Ring 0 ~ 3。正常情况下,application 工作在最低特权级,即 Ring 3,而 kernel 工作在最高特权级,也就是 Ring 0,因为有许多硬件操作必须要在该级别下才能完成。在虚拟化的情况下,也就是有多个 OS 同时运行的情况下,显然这多个 OS 不能同时运行于 Ring 0,因为 OS 需要运行的某些 Ring 0 特权指令将互相干扰。因此一般的解决方案是将虚拟化软件(通常称作 Virtual Machine Monitor,或 hypervisor)放在 Ring 0,而将运行在虚拟机里的 guest OS 放到 Ring 1 或 Ring 3 中。一个正常的硬件设计是,当这些原本应该运行在 Ring 0 级别的指令在非 Ring 0 的级别里被执行时,处理器报错,这样运行在 Ring 0 的 hypervisor 就能捕获该错误,从而做相应的处理(比如模拟或替换该指令)实现虚拟化,然而 x86 处理器有一些特权指令在 Ring 0 及非 Ring 0 下都能执行, 并且有不同的含义,这就使得运行在 Ring 0 级别里的 hypervisor 无法捕获该指令,而该指令的运行也于原本的意义不同。
 
    对此 VMWare 的解决方案是 Binary Translation,也就是 hypervisor 提前扫描 guest OS 待运行的指令,发现有这种无法捕获或无法虚拟化的特权指令时,将其替换成相应的一系列可捕获的指令,从而实现 guest OS 的虚拟化。当然除了 CPU 的虚拟化外,内存,I/O 设备的虚拟化也不那么容易,不过是 CPU 虚拟化方式的不同决定了各解决方案的不同。VMWare 的这种解决方式最大的优点是 guest OS 无需修改就可以运行在 VMWare 的虚拟机上,当然这个优点是相对于后来出现的 Xen 而言的,这种虚拟化方式也称作 Full Virtualization。
 
    VMWare 的 Full Virtualization 解决方案一个致命的缺点是性能上的瓶颈,因为 hypervisor 要在运行时扫描指令,分析并替换,这个消耗是客观无法去掉的。当然 VMWare 采取了很多方法来弥补这些缺陷,使得虚拟机的运行不至于慢的难以忍受,造成的结果就是实现相当复杂。因此在 VMWare 掀起了虚拟化的浪潮之后,许多想投入到这个领域中去的人开始想办法从其它角度来解决 x86 难以虚拟化的难题。
 
Xen 的出现以及 Paravirtualization
 
    Xen 的开发人员就想出了一个巧妙的办法。Xen 最初始于剑桥大学的一个研究项目,他们的出发点是既然 x86 系统难以虚拟化,那么我就假定 guest OS 运行在一个类似 x86 的平台上,该平台由 Xen 来提供。具体点说就是 Xen 实现了一个类似微内核这样的系统,该系统运行在物理硬件平台上(Ring 0 级别),而 guest OS 运行在 Xen 上(Ring 1 级别),于 VMWare 不同的是,运行在 Xen 上的 guest OS 需要修改,因为 Xen 提供或虚拟的硬件环境已不再是 x86 平台,而是一个类 x86 平台,当然再上面的 application 不需要修改。这种虚拟化的方式称作 Paravirtualization。
 
    这就意味着,guest 原本需要运行某些 Ring 0 级别的特权指令才能完成的任务,现在要修改为调用 Xen 提供的相应的指令(称作 hypercall,从实现方式来说类似于 system call)。显然开源的易于修改的 Linux 是最好的目标,这也是早期的 Xen 无法支持 Windows 系统的原因。然而 Xen 的架构还远不止与此,由于 Xen 运行在物理硬件与客户机操作系统之间,因此 Xen 的重要性不言而喻,稍有差错就可能导致所有的客户机崩溃,因此要求 Xen 的代码尽量简练,实际上是越少越好,而一个完整的 guest 运行所需要虚拟的硬件除了 CPU 外还有很多,例如内存,I/O 设备等等。显然如果 Xen 即支持底下的硬件设备,又要虚拟上面需要的硬件设备,那么 Xen 的实现无异于重写一个 Linux。Xen 的想法是 Xen 只支持最基本的硬件设备,也就是 CPU,内存,中断等,其它 I/O 设备由一个专门的 guest OS 来支持,而其余的 guest OS 要想访问该设备,需要通过 Xen,然后再传递到该特殊的 guest。Xen 为此将 guest 分为两个级别,一个是有访问 I/O 设备特权的特殊的 guest,称作 Domain0,其它的称作 DomainU。
 
    因此对 Linux 来说,要想运行在 Xen 上,就必须要修改 Kernel 代码,并且根据 Linux 是运行在 Domain0 级别还是 DomainU 级别而修改的代码也不同。早期的 Xen 采用 Linux Kernel 2.6.18 作为基础,进行修改并实现了 Domain0 以及 DomainU 的功能。
 
    由于 Xen 提供的虚拟化解决方式的性能优势,以及 Xen 的开源的特性,Xen 很快就被炒上了天。当初成立该研究项目的大学教授成立了公司,并获得了风投的青睐,继而被 Citrix 收购;各大发行版纷纷抢着支持 Xen 作为自己的虚拟化方案;很多创业公司也一夜之间冒了出来,研究 Xen 或者利用 Xen,以期望在未来的虚拟化与云计算大潮中能博得一位;Xen 俨然成了虚拟化的未来。
 
硬件虚拟化技术的进步以及 KVM
 
    然而技术的发展往往非人所料,由于虚拟化浪潮的热火朝天,以及 x86 平台难以虚拟化的本质,使得 Intel 与 AMD 这两大芯片商开始思考如何在处理器里添加功能克服原有的缺陷。于是在 2006 年,Intel VT-x 与 AMD-V 出现了。简单的说这两个 CPU 扩展就是在保持四个 Ring 特权级别的条件下,分出两个 forms,分别给客户机与 hypervisor 使用,由于每个 form 都有这四个 Ring 级别,因此客户机的特权指令的捕获就可以轻松实现了。硬件技术的出现很快就带动了软件技术的发展,很快有利用这种硬件虚拟化技术的软件出现了,没错,就是 KVM。
 
    比起 Xen 来,KVM 的实现更加简洁而优雅,除了利用硬件的支持,KVM 还利用了现有的 Linux Kernel 的 CPU 调度等机制,因此 KVM 不需要像 Xen 那样重新实现一个复杂的 guest OS 的调度机制,这个任务交给 Linux Kernel 来完成,此时 guest OS 对 Linux Kernel 所在的 host 来说就是一个进程。此外 KVM 的实现方式也不需要修改 guest OS,因此 KVM 的出现很快引起了 Kernel 社区开发人员的兴趣,几乎是在最短的时间内,KVM 就进入了 Kernel,此时 Xen 仍然按照自己的开发模式在按部就班的进行着。
 
Xen 的问题
 
    相对 KVM 来说,Xen 是一个庞大的项目,一个完整的 Xen 的搭建,需要四个组成部分,首先是最底层的 hypervisor,其次是需要修改的 Domain0 与 DomainU Kernel,最后是上层的应用管理进程。可以看出,hypervisor 与 管理进程是独立的,可以轻易安装,然而 Domain0 与 DomainU 却需要修改后的 Kernel 支持。早期 的 Xen 的源代码库里有一个修改后的 2.6.18,可以下载,编译然后安装。
 
    这个办法并不是长久之计,Linux Kernel 的发展是很快的,一劳永逸的办法是尽快将 Xen 对 Kernel 的修改 merge 到上游 Kernel 中去。然而 Xen 的开发人员似乎并不热衷于 merge 对 Kernel 的修改。带来的问题是,对发行版来说,他们不得不花大量的精力来维护 Xen 相关的 Kernel patch,这个问题在 RHEL 5 上达到了登峰造极式的表现,RHEL 5 的 Kernel SRPM 里与 Xen 相关的 patch 有上百个。此外一些早期投入到 Xen 中去的小公司在快速开始后,发现他们不得不面对一些 tricky 的问题,而且很难判断是 Xen hypervisor 的问题还是 Dom0 或 DomU kernel 的问题,或者有时候在 backport 一些最新的 Kernel bug 修复到 Dom0/DomU 时困难重重。Xen 成了这些人的梦魇。
 
    其实 Xen 的开发人员也不是没想过将 Kernel 的修改 merge 到上游去,然而如上面所说,Xen 对 Kernel 的修改是通过类似将 Linux 移植到一个新平台(x86 的一个子平台)的方式进行的,其中有大量的对 x86 平台代码的修改与复制,对此 Kernel 开发人员非常抵触。再加上 Xen 的开发人员并不热衷于此,Xen 进入 Kernel 之路面临着一个个障碍,而且一拖就是几年。
 
    在 KVM 逐渐开始成熟起来,而 Xen 又迟迟无法进入 Kernel 之际,Red Hat 做出了一个艰难的决定,抛弃 Xen,转投 KVM,并收购了最初开发 KVM 的公司。Red Hat 的决定带来了巨大的影响,不少发行版都抛弃了 Xen,很多人开始预言 Xen 即将灭亡,关于 Xen 与 KVM 之争也随处可见,Red Hat 与 始终支持 Xen 的 Novell 就两者的优劣还吵了一架。同时随着 KVM 的成熟,Xen 进入 Kernel 的阻力更大,许多 Kernel 开发人员认为没有必要在 Kernel 里同时支持两个虚拟化框架,有 KVM 就足够了。而有关推动 Xen 修改进入 Kernel 的努力再次失败,Linus 明确表示,Xen 的代码从开发角度来说就是一个混乱,这样的代码进入 Kernel 只会给 Kernel 开发人员带来维护上的灾难,除非 Xen 的开发人员按照 Kernel 的开发规范重写 Kernel 相关的功能,否则 Xen 的修改不可能进入 Kernel。
 
漫漫人生路
 
    在 Linus  明确对 Xen 的问题表态后,Xen 的开发人员开始了漫漫的 Kernel 人生路。此前在 pv_ops 出现后,Xen 的 DomU 部分已经进入了 Kernel,唯有剩下的 Dom0 部分。Xen 的开发人员开始一点一点的重写,提交,被打回,再重新修改提交,经过了两年时间的积累,Xen 对 Kernel 的修改终于在去年 2.6.37 时有了一个质的变化,2.6.37 包含了核心的 Dom0 支持,当然这还不够,Dom0 还需要一些 backend driver 来支持从 DomU 过来的设备访问请求,不过这些相对来说已不那么困难,轻舟已过万重山。
 
Xen vs KVM
 
    与此同时,在 Red Hat 加入 KVM 后,KVM 的发展也在日新月异。KVM 虽然利用了 CPU 的虚拟化功能,但对外围设备尤其是硬盘与网卡的虚拟还是通过 QEMU,这样的 Full Virtualization,效率并不高。为了提高效率,就要像 Xen 那样采用 Paravirtualization 的方式,即 guest 的 Kernel 知道自己访问的硬盘/网卡并不是真正的硬件设备,很快 Kernel 内部有了 VirtIO 的框架。
 
    硬件的发展同样迅速,在第一代虚拟化技术催生了 KVM 这样的软件后,第二代的虚拟化技术致力于在性能上的提高,比如 Intel 的 EPT 以及 VT-d,AMD 的 RVI 以及 IO-MMU。在这些技术被 KVM 采用后(当然也被 Xen 采用),Xen 是否还具有天然的性能上的优势就真不好说了。相反,由于 Xen 的 Dom0 支持迟迟无法进入 Kernel,使得很多人在选择虚拟化技术时不得不三思。天平已然倾向了 KVM。
 
最后
 
    到底 Xen 与 KVM 孰优孰劣,尤其是性能,不是一个轻易就可以下结论的问题。性能上的比试除了产品的架构外,更多依赖于任务本身是 CPU bound 还是 I/O bound,以及在测试过程中对搭建平台的一步步调整。不管怎么说,Xen 依然有存在的价值,Xen 也有大量的用户群。Xen 的 Kernel 部分正式进入 Linux Kernel 是一件值得高兴的事情,相信很多发行版将重新开始支持 Xen,至少在虚拟化技术前,我们又有了一个方便的选择。对于 Xen 来说,这也意味着它与 KVM 的竞争又站到了同一起跑线上。
 
    纵观 Xen 这短短几年的发展,既有巅峰时的人人追捧,也有没落时的失意。除了虚拟化大环境技术上的变迁外,更主要的原因在于 Xen 的开发策略没有坚持通常所说的上游优先(upstream first),也就是在代码还没有进入上游的 Kernel 之前,就发布出去,从而为日后的弯路打下了基础。这样的教训令人足戒。
Xen 的 Dom0 虽然进入了 Kernel,但 Xen 的故事并未结束,Xen 仍然有一些代码需要进入 Kernel,Xen 本身对硬件虚拟化技术的利用也有待提高,不管怎么说,Xen 又重新回到了人们的视野,至于 Xen 是否还能回到巅峰,只能拭目以待了。
 
资源
 
严格来说,本文的很多术语并不完全准确,所以,如果您有兴趣,您可以延伸阅读:
  1. 我爱 Wikipedia: Virtualization, Hardware Virtualization, x86              Virtualization, Full Virtualization, Paravirtualization, VMWare, Xen,      KVM。 
  2. Intel 的网站上有许多非常棒的关于 Virtualization 的文章,比如这一篇。 
  3. VMWare 的网站上有许多非常棒的关于 Virtualization 的文章,比如这一篇。
  4. Xen 的著名的论文以及架构介绍。 
  5. KernelTrap 对 KVM 的主要开发者的专访。 
  6. LWN 上 Virtualization 相关的文章 Xen: finishing the job, Xen again。 
 
来源:草根网(www.20ju.com) - 互联网界的读者文摘
原作者:开源小厨 (原文链接:http://www.20ju.com/content/V170833.htm)