KVM的十年(2016)

KVM于2006年10月19日被它的缔造者Avi Kivity首次发布在Linux内核邮件列表的这个提交中。

第一版的KVM补丁支持VMX指令集,这个指令集刚被Intel公布不久。紧接着又支持了AMD的SVM指令集。这个补丁在2006年12月合并进了上游的内核中,在次年的2月随着2.6.20版本内核一起发布。

背景

在没有新的虚拟化扩展的支持下,在x86架构上运行多个guest操作系统是比较困难的:

  • 有些指令只能够在最高特权级(ring0)运行,无法在不影响其他操作系统的前提下,将这种操作权限开放给每个操作系统;
  • 此外,有些指令在较低权限级别执行时不会产生trap,尽管他们需要更高的特权级才能正确地工作。因此,在更低特权级上运行guest操作系统,然后ring0上运行一个hypervisor也不是一个解决方法;

VMX和SVM指令在x86架构上引进了一种新的ring,ring1。这是VMM或者hypervisor运行的特权级。这个VMM为各种操作系统对硬件的访问进行仲裁,以便它们可以在常规的x86环境中继续正常运行。

在一个硬件系统上运行多个guest系统有很多理由:

  • 通过虚拟机管理工具可以很方便地部署和管理多个guest系统;
  • 通过在更新、功能更强的硬件上托管多个操作系统及其相应的应用程序和服务,它还可以降低能耗和冷却成本;
  • 通过虚拟机监控程序模拟旧硬件,在较新的硬件上运行老的操作系统和应用程序,而无需进行任何更改来适应较新的硬件;

在引入KVM的时候,Xen是事实上的开源hypervisor。由于Xen是在x86上提供虚拟化扩展(VT-X/AMD-V)之前引入的,所以它使用了不同的设计。

  • 首先,他需要运行一个经过修改的guest内核;
  • 其次,Xen接管了host内核的角色,将Linux降级为仅作为Xen特殊的“Dom0”虚拟机的一部分来管理I/O设备 这意味着该系统不能真正地被称为Linux系统——甚至客户操作系统都是用(当时)非上游代码修改过的Linux内核。

Kivity是在以色列初创公司Qumranet工作时开始开发KVM的,当时他的工作是修复公司正在进行的与Xen相关的工作中。最初的Qumranet产品想法是在两个不同的vm之间复制机器状态,以实现容错。Qumranet的工程师们很快就意识到,Xen的局限性太大,其模型也不适合他们的需求。当时虚拟化扩展正被引入到AMD和Intel的cpu中,因此Kivity启动了一个基于新的硬件虚拟化规范的编外项目——KVM,它将被用作容错解决方案的管理程序。

开发模型

从一开始,Kivity编写代码时就考虑到了将它与上游保持一直。KVM模型的目标之一是尽可能多地重用现有功能:利用Linux完成绝大多数工作,KVM只作为一个驱动程序,处理由硬件暴露的新的虚拟化指令。这使得KVM可以获取所有Linux开发者提供给系统的新的特性,例如增强CPU调度,内存管理,电源管理等等;

这种模式也适用于Linux生态系统的其他部分。最初只是考虑虚拟化而设计的特性在一般的用例中同样变得有用且被广泛采用。例如[[transparent hug pages 透明大页]]。操作系统和VMM没有分割成两个独立的社群,大家在同一个项目中工作。

由于VM能够被当作一个常规的进程进行监控,对VM的管理也变得简单很多。现在,perf可用于监视host上的guest活动并识别性能瓶颈,进一步的芯片组改进还将允许从host测量guest进程性能。

KVM的另一面在用户空间,用来提供给guest操作系统的机器就是在这里构建的。kvm-userspace就是从[[QEMU]]项目fork来的。QEMU是一个机器模拟器——它可以为它支持的各种体系结构运行未经修改的OS映像,并为它所运行的主机体系结构模拟那些体系结构的指令。这当然是非常慢的,但是QEMU项目的优点是它已经为x86体系结构模拟了很多设备——比如芯片组、网卡、显示适配器等等。

kvm-userspace减少了仿真部分的代码,只允许x86-on-x86以及使用[[Using the KVM API KVM API]]作为hostCPU上真正运行guest系统。当guest系统执行一个特权操作,CPU将退出到VMM的代码。接着KVM会接管,如果KVM能够自己为这个请求提供服务,那么它就会提供服务,并将控制权交还给guest系统。这是一个lightweight exit。如果KVM无法服务这个操作,例如设备模拟,它就会退出到QEMU。这意味着要从主机Linux内核退出到用户空间,因此这被称为heavyweight exit

该模型的一个缺点是需要维护QEMU的分支。早期的开发人员将重心放在使内核模块稳定上,同时让越来越多的guest顺畅无阻地运行。这意味着花费在设备模拟上的时间就少了,因此,为使这些代码适合上游用户而重新编写这些代码的工作仍然处于较低的优先级。

Xen的HVM模式(使用硬件虚拟化指令的模式)同样从QEMU上fork了设备模拟相关的代码。此外,QEMU对于x86-on-x86有自己的非上游Linux内核加速模块(KQEMU),它消除了仿真层,使得x86客户机在x86的硬件上运行的更快。要集成所有这些东西,需要一个能够理解所有项目的各种需求的维护者。Anthony Liguori成为了QEMU项目的维护者,并且得到了Xen和KVM社区的信任。随着时间的推移,分支被消除了,现在KVM和Xen使用上游的QEMU进行它们的设备模型仿真。

do one thing, do it right以及everything is a file的理念在KVM中充分体现。KVM API允许在Linux系统上创建vm——或者沙盒。它们可以在内部运行操作系统,或者运行任何不会干扰运行系统的代码。这也意味着还有其他一些不像QEMU那么重量级或功能强大的用户空间的实现。可以通过KVM VM快速引导到小型应用程序或专用操作系统的工具开始出现——其中最流行的工具就是[[kvmtool]]。

开发者感兴趣的

自从KVM项目最初发布以来,许多黑客都开始对KVM感兴趣。对KVM的入侵非常方便:安装新的VMM不需要重新启动系统。只需重新编译KVM模块、删除旧模块并加载新编译的模块即可。这在早期的稳定和改进阶段非常有帮助。与编译新的VMM、安装它、更新引导加载程序并重新引导系统相比,调试过程要快得多,开发人员更喜欢这种工作方式。另一个优点是,运行虚拟机不需要root权限,这在开发系统上可能不太重要,但对于我的工作-开发笔记本电脑却是必不可少的。

KVM模块和QEMU分离带来的另一个方便的调试技巧是,如果某些东西在KVM模式下不能工作,但在模拟模式下工作,那么故障很可能出现在KVM模块中。如果某些来宾操作系统在这两种模式中都不能工作,则故障在设备模型或QEMU中。

早期的KVM发布模型也帮助我们获得了轻松的开发体验:即使KVM项目是上游Linux内核的一部分,Kivity还是在单独的发布系列中维护KVM代码。定期发布新的KVM版本中包括KVM模块的源代码、用于在任何受支持的Linux内核上编译KVM模块的小兼容层,以及KVM-userspace部分。这确保了发行版内核(拥有KVM模块的旧版本)可以通过编译来自该内核的最新KVM版本的模块而不加修改地使用。

兼容性层需要进行一些维护。它需要通过模拟新的API来确保使用在旧内核上没有的新内核API的新的KVM代码能够继续工作。添加这样的API兼容性函数是一次性的开销,但是对于新的贡献者来说,进入的障碍大大降低了。黑客可以下载最新的KVM版本,根据正在运行的内核编译模块,然后看到虚拟机启动。如果这不能运行,那么开发人员可以发布错误修复补丁。

被广泛地采纳

芯片供应商开始感兴趣并将KVM移植到他们的架构中:

  • 英特尔增加了对IA64的支持以及对x86的特性和稳定性修复;
  • IBM增加了对s390和POWER架构的支持;
  • ARM和Linaro贡献了[[ARM port]];
  • Imagination Technologies增加了MIPS的支持。

开发人员的兴趣也可以在KVM论坛上看到,这是对KVM虚拟化感兴趣的人的年度聚会。在2007年的第一个KVM论坛上,有一些开发人员在一个房间里进行了许多关于当前事态和未来走向的讨论。由Rusty Russell领导的一个小组占据了白板,并开始讨论KVM的半虚拟化接口应该是什么样子。这就是[[VIRTIO]]开始成形的地方。如今,KVM论坛是一个完整的会议,有并行的轨道、数十位发言者和数百名与会者。

随着时间的推移,很明显KVM内核模块并不是最活跃的—指令模拟或多或少已经完成,而且大多数发行版都提供了最新的Linux内核。焦点转移到了用户空间:添加更多的设备模拟,使现有设备性能更好,等等。然后KVM版本开始更多地关注用户空间部分,并且简化了兼容层的维护。此时,即使存在kvm-userspace分支,也要努力确保新特性进入QEMU项目,而不是kvm-userspace项目。Kivity也开始提供从kvm-userspace存储库到QEMU项目的小更改。

当这一切发生的时候,Qumranet改变了方向,现在正在追求使用KVM作为管理程序的桌面虚拟化。2008年9月,红帽公司宣布将收购Qumranet。自从Red Hat Enterprise Linux 5.0发行版以来,Red Hat就支持Xen虚拟机监控程序作为其官方VMM。在RHEL 5.4发行版中,Red Hat开始同时支持Xen和KVM作为管理程序。随着RHEL 6.0的发布,Red Hat只支持KVM。KVM在其他发行版中也继续享受开箱即用的支持。

现在和未来

现在有许多项目使用KVM作为默认的hypervisor:OpenStack、oVirt和ZStack等等。这些项目关注的是KVM主机和多个vm在一个部署中的大规模部署。它们带有很多不同的用例,因此对KVM有许多不同的述求。随着客户操作系统越来越大(RAM和虚拟cpu越来越多),在不产生长时间停机的情况下热迁移变得越来越困难;电信公司的部署需要低延迟的网络数据包处理;因此[[realtime KVM]]是一个值得关注的领域;更快的磁盘和网络I/O一直是一个研究领域。此外,还在努力保持一切安全并减少虚拟机监控程序的占用空间。恶意来宾机如何突破其VM沙箱以及如何减轻此类攻击也是主要关注的领域。

新的硬件更新和设备带来了很多进步。然而,许多工作也花费在优化当前的代码基础、编写新算法和提出新的方法来提高现有基础设施的性能和可伸缩性上。

在未来的十年,讨论的主要主题可能不是关于虚拟机监控程序的开发。更有趣的是了解如何将Linux用作虚拟机监控程序,为运行不受信任的代码(尤其是在移动电话上)和运行云基础设施提供更好的沙盒,使其既普及又不可见。