KVM虚拟化技术

今天是周六,看到一片KVM相关的文章,感受写得很不错,翻译了,原文在这里:KVM Technologylinux

 

在开放服务器虚拟化的应用方面,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和敏感指令socket

 

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.