KVM技术

jopen 9年前

原文在这里:KVM Technology


在开放服务器虚拟化的应用方面,KVM虚拟化技术近年来广受关注。自从2006年10 月份诞生以来,其简单的思想激起了Linux内核开发者们的兴趣,在他们的帮助下,KVM的功能得到迅速扩展。目前,KVM得到Red Hat企业版Linux的正式支持,并从版本6开始受到Fujitsu的支持。这篇论文首先解释KVM的实现机制,接着描述它的各个组件。然后就硬件及软件对KVM虚拟化的支持进行介绍,并简要描述Fujitsu为使KVM得以在关键工作任务中使用所进行的改进计划。

 

 1. 简介

近年来,由于各种各样的原因,x86系列CPU服务器的虚拟化技术受到广泛关注。服务器虚拟化技术本身已经存在一段时间了,Intel在他们CPU中提供的(Intel VT)1)和AMD在他们CPU中提供的虚拟化(ADM-V)2)使得开发者们能够在x86硬件上以相对廉价的成本使用虚拟化技术,并且基本能满足性能要求。各种基于软件的服务器虚拟化技术也相继出现,其中(KVM)3) 以开放源码软件(OSS)服务器虚拟化技术的形式迅速走在了前列。KVM是基于Intel VT-x note1)和AMD-V的设计,使用相对简单的架构(结构)来获得虚拟化。KVM的基本思想于2006年10月份由Avi Kivity(当时的Qumranet,一家以色列公司)首次公布。Linux内核开发者们被KVM简洁的设计所吸引,迅速采纳并扩展了它的功能。KVM目前得到Red Hat企业版Linux的正式支持,并从版本6开始受到Fujitsu的支持。这篇论文描述KVM的简单机制,并简要介绍硬件及软件各层面对KVM的支持,默认以Intel VT-x CPU的功能为例。

 

2. KVM机制

为使读者对KVM机制有一个基本的认识,这一节首先介绍Intel VT-x,然后介绍快速模拟器QEMU,它是KVM的一个重要OSS组件。


2.1 Intel VT-x和敏感指令

KVM会使用到 Intel VT-x的功能,KVM的设计者把KVM当作Linux内核的功能来实现.note2)。接下来是对KVM的一个概览,以辅助理解KVM。Intel VT-x可以被看作是一个“检测到敏感指令执行时切换到hypervisor的功能”,如图1所示。Hypervisor是物理机上操控VM(客户机系统)的一个控制程序。敏感指令有两种定义:

1) “控制敏感指令”试图修改系统资源状态。

2) “行为敏感指令”根据系统资源的状态进行操作。

 


概念上,虚拟机上的程序执行
控制敏感指令影响物理机的行为,虚拟机上的程序执行行为敏感指令表现为在虚拟机上执行的效果,和它们在物理机上执行产生不同的效果。如果一个程序试图执行这些指令而不被阻止,将会给hypervisor和客户机系统带来严重的问题。因此,有必要让CPU在检测到一个敏感指令的开始执行并把它转向到 hypervisor,让hypervisor替代应用程序去执行这个敏感指令。然而,x86 CPU在设计之初并没有考虑到虚拟化的需求,所以有一些敏感指令试图在客户机系统执行时无法被CPU检测到,结果导致了hypervisor无法代替客户机系统去执行那些指令。Intel VT-x就是为应对这个问题而被开发的,它给处理器添加了新的执行模式,在CPU检测到这些敏感指令时进行模式切换,这样hypervisor就可以代替初始的那个程序去执行敏感指令。

具体来说,Intel VT-x添加了两个执行模式:VMX根操作和VMX非根操作模式,VMX代表了“virtual machine extension”。如图2所示,VMX非根模式是客户机系统的执行模式。如果在这个模式下试图执行敏感指令,CPU发现并切换到VMX根操作模式,即切换到hypervisor所处的执行模式。这个转换叫“VM Exit”,表示控制权转移到了hypervisor,使其能够代替客户机系统去执行敏感指令。

 Intel VT-x引入了两条新的指令,VMLAUNCH和VMRESUME,使得可以切换到VMX非根操作模式,叫“VM Entry”。KVM的主要角色就是处理VM退出和执行VM Entry指令。KVM在Linux内核中以一个模块的形式实现。


2.2 KVM和QEMU

KVM内核模块自己无法创建VM,要创建VM,它必须使用QEMU,QEMU以一个用户空间进程存在 6)。QEMU本质上是一个硬件模拟器,它作为一个开放源码软件,模拟标准的x86 PC和其它的架构,其存在早于KVM也不依赖KVM来运行。作为一个基于软件的模拟器,QEMU逐条地解释和执行CPU指令,意味着性能受限。然而,如果有三个条件能够满足,QEMU可以在保持其创建VM功能的同时大大提升其性能。

1) 目标指令可以直接被CPU执行。

2) 在VMX非根操作模式下,指令可以不经修改的被CPU直接执行。

3)  不能直接执行的指令可被鉴别并传递给QEMU进行模拟处理。

 KVM的开发就是基于这个思想,它使得既可以创建虚拟机又能最大化的复用已有的开放源码软件(OSS),只需做最小量的修改。正是这个原因,使KVM得到很多Linux内核开发者的支持。

 

QEMU/KVM的执行流程如图3所示。首先,KVM内核模块创建(图中step 0)一个文件"/dev/kvm",这个文件使得QEMU可以将各种各样的请求信息传递给内核模块来执行hypervisor功能。当QEMU启动执行一个客户机系统,它反复地调用ioctl()系统调用,在调用中指定这个文件(或者从这个文件派生的文件描述符)。要开始执行客户机系统时,QEMU调用 ioctl()指示(step 1)KVM内核模块启动客户机系统。KVM内核模块转去执行VM Entry(step 2)并执行客户机系统。之后当客户机系统欲执行一条敏感指令时,VM Exit被执行(step 3),KVM获取退出的原因。如果需要QEMU的干预来执行I/O任务或其它任务,控制转移到QEMU进程(step 4),然后QEMU执行该任务。执行完毕后,QEMU又一次调用ioctl()系统调用,请求KVM继续执行客户机系统(i.e., 执行流程返回到step 1)。这个QEMU/KVM流程在VM的整个模拟过程中不断反复。

 


QEMU/KVM有一个相对简单的结构

1) KVM内核模块的实现将Linux内核变成一个hypervisor。

2) 每个客户机系统有一个QEMU进程。有多少个客户机系统在运行,就相应的有多少个QEMU进程在运行。

3) QEMU是一个多线程程序,客户机系统的每个虚拟CPU(vCPU)对应一个QEMU线程。图3中的步骤1-4都在这些线程中进行。

4) 从Linux内核来看,QEMU线程就和普通的用户进程一样。对应于客户机虚拟CPU的线程接受Linux内核调度器的管理,这和其它进程的线程无异。

 

3. KVM组件

这一节介绍KVM相关的组件而不是QEMU,并描述KVM的整体结构。QEMU本身通过字符用户接口(CUI)以一个简单的同名命令启动(a simple command of the same name via a character user interface)。如果在客户机系统运行时执行ps命令,QEMU的运行状态就会显示,如例子中所示:

[goto@lifua ~ ]$ ps auxw |grep qemu
qemu  ......  /usr/bin/qemu-kvm -S -M
fedora-13 -enable-kvm -m 1024 -smp 1, sockets=1,
cores=1, threads=1 .....
-drive file=/home/goto/kvm_image/fedora13.img,
..... -device rtl8139, vlan=0, id=net0,
mac=52:54:00:65:03:a0 ......


命令项“-m 1024”和“-smp 1”分别表示客户机系统内存容量和CPU数量。虽然上面的例子中只显示了实际行数大概三分之一,但所有QEMU的设置,如设备的设置,都是通过QEMU命令参数的形式传递了的。

不出所料,我们没有必要在命令中直接指定所有的选项。基于这个原因,出现了一个叫"virt-manager," 7)的图形用户接口(GUI),供用户管理一个或多个客户机系统。virt-manager可在Red Hat企业版Linux和其它的一些操作系统中使用。图4是多个客户机系统运行时的一个截图。左上角窗口是virt-manager的屏幕,左下角和右边窗口是客户机系统屏幕,表示有两个客户机系统在运行。这个截图显示的是虚拟机在Fedora发行版上运行的情况,RHEL6上的情况会有些不同。

 

 

 除了这些GUIs,virt-manager还能以CUI的形式("virsh")供用户操作客户机系统。KVM的整体结构,从GUI到Linux内核,包括以下五个组件:

1) virt-manager

一个用来管理VM的GUI/CUI用户接口;它使用libvirt调用VM的各种功能,之后会有描述。

2) libvirt

一个工具及接口t(tool-and-interface)库 8),作为较通用的服务器虚拟化软件,它支持Xen,VMware ESX/GSX,当然,还有QEMU/KVM。

3) QEMU

一个和KVM内核模块交互的模拟器,处理多种客户机系统请求如I/O;一个QEMU进程对应一个客户机系统。

4) KVM内核模块
从狭义上来说,KVM是一个Linux内核模块,处理客户机系统的VM Exits和执行VM Entry指令。

5) Linux内核

既然QEMU作为一个普通的用户进程运行,相应客户机系统的调度就由Linux内核自己来处理。如果我们对图3进行修正,使它包含virt-manager和其它的组件,就得到了KVM的整体构架图,如图5所示。所有的组件都是开放源码软件(OSS)。

 

4. KVM硬件和软件支持的功能

服务器虚拟化最关注的是性能,理想的情况下,虚拟机的性能不要比物理机性能差。为此,除了上文描述的基本的KVM机制,各种不同的硬件和软件支持虚拟化功能争相出现。最基本的目标就是使用它们来改善KVM的性能。这一节将介绍几个这样的功能。

1) Extended Page Table(EPT)

EPT扩展了CPU提供的地址转换机制(MMU: 内存管理单元)。虚拟机包含两部分结构,一部分是hypervisor,另一部分是客户机系统。以往的MMU结构在设计时没有考虑到虚拟机的需求,不能直接使用。

在EPT之前,需要使用软件方案进行地址转换,这种技术叫“影子页表”。EPT使得虚拟机的“物理地址”由CPU转换成物理机的物理地址,软件转换方案也就不需要了。KVM充分利用了EPT提供的功能,使得虚拟机性能得到大幅提升。

2) VT-d

VT-d是I/O设备(IOMMU)的地址转换机制。它为每种设备功能提供了内存地址转换表(和MMU页表的数据结构完全一致)。有了VT-d,客户机的内存地址可被指定为设备数据传输的目标地址,数据直接被传递到客户机操作系统。VT- d属于芯片级功能,需要固件的支持。相应的,如果固件和Linux内核都支持VT-d,后者会识别VT-d功能并使用它。

3) virtio

虚拟机设备通常由QEMU设备模拟功能进行创建和处理。这种模拟的开销很高,因此 I/O性能表现不佳。为了克服这个问题,引入了一种叫“virtio”的机制。Virtio准备一个缓冲区,该缓冲区可同时被客户机系统和QEMU访问。使用这个缓冲区,对多个数据项的I/O处理就可以同时进行,减少了QEMU模拟的开销进而或得高速的处理方案。从客户机系统来看,这种机制就像是访问一个 virtio PCI设备一样。通过在客户机系统中实现一个virtio驱动(当然,Windows需要一个virtio驱动),可获得virtio带来的好处并达到高速I/O的效果。

4) Kernel Samepage Merging(KSM)

同一个物理机上不同虚拟机可能在运行同样的操作系统和应用程序。在这种情况下,它们很有可能有些内存区域具有相同的数据。将这些内存区域整合成一个区域将减少内存的使用量。基于这一点,KSM功能 9)被添加到KVM。KSM功能使用一个“ksmd”内核线程定期监控进程内存使用情况并自动将重复的内存页合并成一个公共页。理想的情况下,所有内存页都会被拿来比较看是否有重复数据,但持续地比较所有系统进程使用的所有内存页会极其低效。由于这个原因,Linux提供一种机制,即可以通过 madvice()系统调用的第三个参数(advice参数)来指定哪个内存区将被考虑作为KSM进行合并的对象。QEMU在给客户机分配内存时使用这个系统函数,用户就立即享受到KSM的功能。在RHEL6中,这个功能在系统初始化状态下就是有效的。

 

5. KVM未来的增强

我们的目标就是使得KVM能够在关键任务系统和应用领域被使用,但为改善功能和质量,还有很多地方需要提升。下面介绍的是Fujitsu的几项开发计划,目的是提升KVM功能。

1)  libvirt功能性和质量上的提升

相对于KVM内核模块和QEMU的成熟度,libvirt的功能还远未完整,这使得KVM的功能无法被完全挖掘,而且libvirt还没有达到稳定和质量良好的状态。因此,提升libvirt的功能性和质量是一个紧迫的开发任务。

2) 资源管理功能的提升

按预期,KVM会和Cgroup 10)整合,Cgroup是RHEL6中引进的一个资源管理功能。当前,Cgroup的功能可用于多种资源的分配,如给一个进程分配某个特定数目的 CPU。然后,从控制虚拟机系统的角度来看,KVM和Cgroup的整合还是有很多问题需要处理,比如对I/O没法进行足够的控制。因此提升Cgroup 功能也是一项计划。

3) Machine-check support(机器检查支持)

物理机不可纠正错误,如multi-bit错误发生的信息要能够被传递给客户机系统。关于这个,一个基本的框架已经被合并到KVM,但是专门针对KVM机器检查的支持还需要提升,以使客户机系统可以进行内存错误的恢复。

 

6. 结论

这篇论文描述了KVM的基本机制和Red Hat企业版Linux 6中服务器虚拟化支持的标准功能,同时介绍了Fujitsu在开发和提升KVM功能方面的努力。Fujitsu期望这些开发工作使得KVM在未来成为客户关键任务系统中一个重要的组件。

 

参考


1)    Intel: Virtualization (Intel VT).
http://www.intel.com/technology/virtualization/technology.htm?iid=tech_vt+tech
2)     AMD Virtualization.
http://sites.amd.com/us/business/it-solutions/virtualization/Pages/virtualization.aspx
3)     Main Page—KVM.
    http://www.linux-kvm.org/page/Main_Page
4)     [PATCH 0/7] KVM: Kernel-based Virtual Machine.
    http://marc.info/?l=linux-kernel&m=116126591619631&w=2
5)     Gerald J. Popek, Robert P. Goldberg: Formal Requirements for Virtualizable Third Generation Architectures, (1974).
    http://portal.acm.org/ft_gateway.cfm?id=361073&type=pdf&CFID=5009197&CFTOKEN=14838199
6)     About—QEMU.
    http://wiki.qemu.org/Main_Page
7)     Virtual Machine Manager.
    http://virt-manager.et.redhat.com/
8)     Libvirt: The virtualization API.
    http://libvirt.org/
9)     [PATCH 0/4] ksm - dynamic page sharing driver for linux.
    http://marc.info/?l=linux-kernel&m=122640987623679&w=2
10)     H. Ishii: Fujitsu’s Activities for Improving Linux as Primary OS for PRIMEQUEST.
   


note 1)    Intel VT is the generic name of Intel’s virtualization support function consisting of Intel VT-x for x86 processors like Core 2 Duo and Intel Xeon, Intel VT-i for Itanium 2, and Intel VT-d supporting I/O virtualization.

note 2)    The advantage of this is that a kernel function can easily support hypervisor operation given the high affinity between the kernel and hypervisor.