剖析 Linux hypervisor

KVM 和 Lguest 简介

Linux® 的最重要创新之一就是转变为hypervisor(或运行其他操作系统的操作系统)。现在涌现许多使用 Linux 作为内核的 hypervisor 解决方案。本文探索 hypervisor 背后的原理,以及两个使用 Linux 作为平台的 hypervisor(KVM 和 Lguest)。

M. Tim Jones, 顾问工程师, Emulex Corp.

2009 年 6 月 29 日

  • +内容

hypervisor 之于操作系统类似于操作系统之于进程。它们为执行提供独立的虚拟硬件平台,而虚拟硬件平台反过来又提供对底层机器的虚拟的完整访问。但并不是所有 hypervisor 都是一样的,这是件好事,因为 Linux 就是以灵活性和选择性著称。本文首先简要介绍虚拟化和 hypervisor,然后探索两个基于 Linux 的 hypervisor。

虚拟化和 hypervisor

developerWorks 上 Tim 所著的其他剖析…… 系列文章

  • Linux flash 文件系统剖析
  • Security-Enhanced Linux(SELinux)剖析
  • 实时 Linux 架构剖析
  • Linux SCSI 子系统剖析
  • Linux 文件系统剖析
  • Linux 网络栈剖析
  • Linux 内核剖析
  • Linux slab 分配器剖析
  • Linux 同步方法剖析
  • Tim 所著的所有剖析…… 系列文章

我们首先花一点时间理解为什么虚拟化很重要,以及 hypervisor 的扮演的角色。(要更多地了解这两个主题,请参见 参考资料)。

在本文中,虚拟化 就是通过某种方式隐藏底层物理硬件的过程,从而让多个操作系统可以透明地使用和共享它。这种架构的另一个更常见的名称是平台虚拟化。在典型的分层架构中,提供平台虚拟化的层称为 hypervisor (有时称为虚拟机管理程序 或 VMM)。来宾操作系统称为虚拟机(VM),因为对这些 VM 而言,硬件是专门针对它们虚拟化的。图 1 简单的展示了这个分层架构。

图 1. 显示常用硬件虚拟化的简单分层架构
剖析 Linux hypervisor_第1张图片

平台虚拟化的好处很多。美国环境保护署(EPA)报告的一组有趣的统计数据就证明了其好处。EPA 研究服务器和数据中心的能源效率时发现,实际上服务器只有 5% 的时间是在工作的。在其他时间,服务器都处于 “休眠” 状态。在单个服务器上的虚拟化平台能够改善服务器的利用率,但是减少服务器的数量才是它的最大功用。减少服务器数量意味着减少不动资产、能耗、冷却和管理成本。使用更少的硬件还能提高可靠性。总之,平台虚拟化不仅带来技术优势,还能创造成本和能源优势。

在图 1 中可以看到,hypervisor 是提供底层机器虚拟化的软件层(在某些情况下需要处理器支持)。并不是所有虚拟化解决方案都是一样的,您可以在 参考资料 中了解更多的虚拟化方式。继续讨论进程,操作系统将对机器的底层资源的访问虚拟化为进程。hypervisor 也做一样的事情,但其对象不是进程,而是整个来宾操作系统。

hypervisor 分类

hypervisor 可以划分为两大类。首先是类型 1,这种 hypervisor 是直接运行在物理硬件之上的。其次是类型 2,这种 hypervisor 运行在另一个操作系统(运行在物理硬件之上)中。类型 1 hypervisor 的一个例子是基于内核的虚拟机(KVM —— 它本身是一个基于操作系统的 hypervisor)。类型 2 hypervisor 包括 QEMU 和 WINE。

hypervisor 的构成

hypervisor(不管是什么类型)仅是一个从其来宾操作系统抽象机器硬件的分层应用程序。通过这种方式,每个来宾操作系统看到的仅是一个 VM 而不是真实的硬件机器。我们大致看一下 hypervisor 的内部组成,以及它在 VM(来宾操作系统)上的表示。

在较高级别上,hypervisor 需要少量设施启动来宾操作系统:一个需要驱动的内核映像、一个配置(比如 IP 地址和所需的内存量)、一个磁盘盒一个网络设备。磁盘和网络设备通常映射到机器的物理磁盘和网络设备(如图 2 所示)。最后,需要使用一组来宾操作系统工具启动和管理来宾操作系统。

图 2. 在假设 hypervisor 中的最小资源映射
剖析 Linux hypervisor_第2张图片

然后,一个简化的 hypervisor 架构实现最后的关键功能,从而使来宾操作系统可以和宿主操作系统同时运行。实现这个功能需要一些特定的要素,如图 3 所示。首先,类似于将用户空间应用程序和内核函数连接起来的系统调用,一个通常可用的虚拟化调用(hapercall,hypervisor 对操作系统进行的系统调用)层允许来宾系统向宿主操作系统发出请求。可以在内核中虚拟化 I/O,或通过来宾操作系统的代码支持它。故障必须由 hypervisor 亲自处理,从而解决实际的故障,或将虚拟设备故障发送给来宾操作系统。hypervisor 还必须处理在来宾操作系统内部发生的异常。(毕竟,来宾操作系统发生的错误仅会停止该系统,而不会影响 hypervisor 或其他来宾操作系统)。hypervisor 的核心要素之一是页映射器,它将硬件指向特定操作系统(来宾或 hypervisor)的页。最后,需要使用一个高级别的调度器在hypervisor和来宾操作系统之间传输控制。

图 3. 简化的基于 Linux 的hypervisor

Linux hypervisor

本文探索两个基于 Linux 的 hypervisor 解决方案。首先是 KVM,它是首个被集成到 Linux 内核的 hypervisor 解决方案,并且实现了完整的虚拟化。其次是 Lguest,这是一个实验 hypervisor,它通过少量的更改提高准虚拟化。

KVM

KVM 针对运行在 x86 硬件硬件上的、驻留在内核中的虚拟化基础结构。KVM 是第一个成为原生 Linux 内核(2.6.20)的一部分的 hypervisor,它是由 Avi Kivity 开发和维护的,现在归 Red Hat 所有。

这个 hypervisor 提供 x86 虚拟化,同时拥有到 PowerPC® 和 IA64 的通道。另外,KVM 最近还添加了对对称多处理(SMP)主机(和来宾)的支持,并且支持企业级特性,比如活动迁移(允许来宾操作系统在物理服务器之间迁移)。

KVM 是作为内核模块实现的,因此 Linux 只要加载该模块就会成为一个hypervisor。KVM 为支持 hypervisor 指令的硬件平台提供完整的虚拟化(比如 Intel® Virtualization Technology [Intel VT] 或 AMD Virtualization [AMD-V] 产品)。KVM 还支持准虚拟化来宾操作系统,包括 Linux 和 Windows®。

这种技术由两个组件实现。第一个是可加载的 KVM 模块,当在 Linux 内核安装该模块之后,它就可以管理虚拟化硬件,并通过 /proc 文件系统公开其功能(见图 4)。第二个组件用于 PC 平台模拟,它是由修改版 QEMU 提供的。QEMU 作为用户空间进程执行,并且在来宾操作系统请求方面与内核协调。

图 4. KVM hypervisor 的高级别视图
剖析 Linux hypervisor_第3张图片

当新的操作系统在 KVM 上启动时(通过一个称为 kvm 的实用程序),它就成为宿主操作系统的一个进程,因此就可以像其他进程一样调度它。但与传统的 Linux 进程不一样,来宾操作系统被 hypervisor 标识为处于 “来宾” 模式(独立于内核和用户模式)。

每个来宾操作系统都是通过 /dev/kvm 设备映射的,它们拥有自己的虚拟地址空间,该空间映射到主机内核的物理地址空间。如前所述,KVM 使用底层硬件的虚拟化支持来提供完整的(原生)虚拟化。I/O 请求通过主机内核映射到在主机上(hypervisor)执行的 QEMU 进程。

KVM 在 Linux 环境中以主机的方式运行,不过只要底层硬件虚拟化支持,它就能够支持大量的来宾操作系统。您可以在 参考资料 部分找一个到受支持的来宾操作系统的列表。

Lguest(以前的 lhype)

Lguest hypervisor 由澳大利亚 IBM 的 Rusty Russell 开发,它采用完全不同的方式实现虚拟化。Lguest 并没有为运行任意操作系统提供完整的虚拟化支持,而是为支持 x86 的 Linux 来宾操作系统(也称为Linux-on-Linux 虚拟化)提供轻量级准虚拟化。这意味着来宾操作系统知道自己正在被虚拟化,并且这同时还会改进性能。但是,Lguest 不需要 QEMU 提供平台虚拟化(像在 KVM 中一样)来改进性能。使用 Lguest 这种方法还减少了总代码需求,仅需在来宾操作系统和宿主操作系统中使用一个瘦层。现在,我们探索这些变化,并查看 Lguest 环境的高级别架构。

如图 5 所示,来宾操作系统包含一个 Lguest 代码瘦层(根据定义,就是准虚拟化)。这段代码提供许多服务。在最高的级别,有一些代码可以决定正在启动的内核是否被虚拟化。此外,还有一个通过虚拟化调用将特权操作发送给宿主操作系统的抽象层(通过 paravirt_ops 实现)。例如,来宾操作系统不能禁用中断,以使这些请求在宿主操作系统中执行。您还可找到一个为来宾操作系统实现设备抽象的总线,以及一组实现控制台、虚拟块驱动器和虚拟网络驱动器(允许与其他来宾通信)的简单驱动器。

图 5. 实现 x86 准虚拟化的 Lguest 的架构

内核部分被实现为可加载的模块,即lg.ko。这个模块包含来宾操作系统通向宿主内核的接口。第一个组件是切换器,它实现一种方法,让来宾操作系统在执行时根据上下文进行切换。这个模块还实现 /proc 文件系统代码(针对 /dev/lguest),该代码实现到内核和驱动器(包括虚拟化调用)的用户空间接口。还有一些代码通过使用影子页表(shadow page-table)和管理 x86 区段来提供内存映射。

最后,内核中的 Documentation 子目录包含启动实用程序(lguest),用于启动新的来宾操作系统实例。这个文件负责两项任务,即使用和记录。

Lguest 从 2.6.23(2007 年 10 月)开始就成为主流内核,并且由 Rusty Russell 开发和维护。它大约包含 5000 行源代码,包括用户空间实用程序。尽管 Lguest 很简单(据说是这样的),但它能提供真正的准虚拟化。不过简单性往往与局限性相随。例如,Lguest 仅虚拟化其他支持 Lguest 的来宾操作系统,并且目前仅能用于 x86 架构。尽管存在这些限制,Lguest 仍然提供一种有趣的虚拟化方式,并且对任何希望研究 Rusty 的代码的人员公开。

Linux hypervisor 的益处

使用 Linux 作为内核开发 hypervisor 有实实在在的好处。最明显的是, 以 Linux 为基础开发 hypervisor 受益于稳步前进的 Linux,以及为改进 Linux 投入的大量工作。从典型的优化、bug 修复、调度和内存管理创新到支持不同处理器架构,Linux 都是一个不断进步的平台(引自 Salisbury 市的 John 的 “站在巨人的肩膀上” 一文)。

不久前已经证明,通过向 KVM 添加一个内核模块,就可以将 Linux 内核转变为 hypervisor。Lguest 进一步改进了这种方法,并且通过受限制的准虚拟化进一步简化了该解决方案。

使用 Linux 作为平台的另一个奇特好处是,除了可以将该平台用作 hypervisor 之外,您还可以将其用作操作系统。因此,除了可以在 Linux hypervisor 上运行多个来宾操作系统之外,您还可以在该级别上运行其他传统的应用程序。所以,不必担心带有新的应用编程接口(API)的新平台,因为您拥有用于开发应用程序的标准 Linux 平台(如果需要监控应用程序或 hypervisor)。标准协议(TCP/IP)和其他有用的应用程序(Web 服务器)和来宾操作系统都是可用的。回顾一下讨论 KVM 时的 图 4:除了来宾操作系统之外,还使用了修改了 KVM 的 QEMU。这是一个标准进程,并展示了 Linux 作为 hypervisor 的强大之处。KVM 在平台虚拟化中利用 QEMU,并使用 Linux 作为hypervisor,因此实现了这个构思,即让来宾操作系统能够和其他 Linux 应用程序协调执行。

结束语

在 hypervisor 开发的过程中,hypervisor 就是新开辟的战场。3 年以前,操作系统是战场的主线,并且控制了一小部分据点。然而,今天战场已转移到 hypervisor,并且 Linux 担任一个明确的角色。

但是,也有声音反对使用 Linux 作为 hypervisor,并且最剧烈的批评来自于夸夸其谈的空论。在数年以前这种情况曾出现在嵌入式领域。今天,作为嵌入式操作系统的 Linux 已是不曾止步的强者。但是我们也有对付批评的办法,通过一些架构上的改进可以让 Linux 成为最强大、最普遍和更灵活的操作系统。

你可能感兴趣的:(剖析 Linux hypervisor)