第2章
KVM原理简介
2.1 硬件虚拟化技术
通过第1章的介绍,大家已经知道KVM虚拟化必须依赖于硬件辅助的虚拟化技术,本节就来介绍一下硬件虚拟化技术。
最早的硬件虚拟化技术出现在1972年的大型机IBM System/370 系统上,而真正让硬件虚拟化技术“走入寻常百姓家”的是2005年年末Intel发布的VT-x硬件虚拟化技术,以及AMD于2006年发布的AMD-V。本书中除了特别说明,默认以Intel的硬件虚拟化技术作为代表来介绍。
2.1.1 CPU虚拟化
CPU是计算机系统最核心的模块,我们的程序执行到最后都是翻译为机器语言在CPU上执行的。在没有CPU硬件虚拟化技术之前,通常使用指令的二进制翻译(binary translation)来实现虚拟客户机中CPU指令的执行,很早期的VMware就使用这样的方案,其指令执行的翻译比较复杂,效率比较低。所以Intel最早发布的虚拟化技术就是CPU虚拟化方面的,这才为本书的主角—KVM的出现创造了必要的硬件条件。
Intel在处理器级别提供了对虚拟化技术的支持,被称为VMX(virtual-machine extensions)。有两种VMX操作模式:VMX 根操作(root operation) 与VMX 非根操作(non-root operation)。作为虚拟机监控器中的KVM就是运行在根操作模式下,而虚拟机客户机的整个软件栈(包括操作系统和应用程序)则运行在非根操作模式下。进入VMX非根操作模式被称为“VM Entry”;从非根操作模式退出,被称为“VM Exit”。
VMX的根操作模式与非VMX模式下最初的处理器执行模式基本一样,只是它现在支持了新的VMX相关的指令集以及一些对相关控制寄存器的操作。VMX的非根操作模式是一个相对受限的执行环境,为了适应虚拟化而专门做了一定的修改;在客户机中执行的一些特殊的敏感指令或者一些异常会触发“VM Exit”退到虚拟机监控器中,从而运行在VMX根模式。正是这样的限制,让虚拟机监控器保持了对处理器资源的控制。
一个虚拟机监控器软件的最基础的运行生命周期及其与客户机的交互如图2-1所示。
软件通过执行VMXON指令进入VMX操作模式下;在VMX模式下通过VMLAUNCH 和VMRESUME指令进入客户机执行模式,即VMX非根模式;当在非根模式下触发VM Exit时,处理器执行控制权再次回到宿主机的虚拟机监控器上;最后虚拟机监控可以执行VMXOFF指令退出VMX执行模式。
逻辑处理器在根模式和非根模式之间的切换通过一个叫作VMCS(virtual-machine control data structure)的数据结构来控制;而VMCS的访问是通过VMCS指针来操作的。VMCS指针是一个指向VMCS结构的64位的地址,使用VMPTRST和VMPTRLD指令对VMCS指针进行读写,使用MREAD、VMWRITE和VMCLEAR等指令对VMCS实现配置。
对于一个逻辑处理器,它可以维护多个VMCS数据结构,但是在任何时刻只有一个VMCS在当前真正生效。多个VMCS之间也是可以相互切换的,VMPTRLD指令就让某个VMCS在当前生效,而其他VMCS就自然成为不是当前生效的。一个虚拟机监控器会为一个虚拟客户机上的每一个逻辑处理器维护一个VMCS数据结构。
根据Intel的官方文档,我们这里列举部分在非根模式下会导致“VM Exit”的敏感指令和一些异常供读者朋友参考,这对于理解KVM的执行机制是必要的,因为KVM也必须按照CPU的硬件规范来实现虚拟化软件逻辑。
1)一定会导致VM Exit的指令:CPUID、GETSEC、INVD、XSETBV等,以及VMX 模式引入的INVEPT、INVVPID、VMCALL、VMCLEAR、VMLAUNCH、VMPTRLD、VMPTRST、VMRESUME、VMXOFF、VMXON等。
2)在一定的设置条件下会导致VM Exit的指令:CLTS、HLT、IN、OUT、INVLPG、INVPCID、LGDT、LMSW、MONITOR、MOV from CR3、MOV to CR3、MWAIT、MWAIT、RDMSR、RWMSR、VMREAD、VMWRITE、RDRAND、RDTSC、XSAVES、XRSTORS等。如在处理器的虚拟机执行控制寄存器中的“HLT exiting”比特位被置为1时,HLT的执行就会导致VM Exit。
3)可能会导致VM Exit的事件:一些异常、三次故障(Triple fault)、外部中断、不可屏蔽中断(NMI)、INIT信号、系统管理中断(SMI)等。如在虚拟机执行控制寄存器中的“NMI exiting”比特位被置为1时,不可屏蔽中断就会导致VM Exit。
最后提一下,由于发生一次VM Exit的代价是比较高的(可能会消耗成百上千个CPU执行周期,而平时很多指令是几个CPU执行周期就能完成),所以对于VM Exit的分析是虚拟化中性能分析和调优的一个关键点。
2.1.2 内存虚拟化
内存虚拟化的目的是给虚拟客户机操作系统提供一个从0地址开始的连续物理内存空间,同时在多个客户机之间实现隔离和调度。在虚拟化环境中,内存地址的访问会主要涉及以下4个基础概念,图2-2形象地展示了虚拟化环境中内存地址。
1)客户机虚拟地址,GVA(Guest Virtual Address)
2)客户机物理地址,GPA(Guest Physical Address)
3)宿主机虚拟地址,HVA(Host Virtual Address)
4)宿主机物理地址,HPA(Host Physical Address)
内存虚拟化就是要将客户机虚拟地址(GVA)转化为最终能够访问的宿主机上的物理地址(HPA)。对于客户机操作系统而言,它不感知内存虚拟化的存在,在程序访问客户机中虚拟地址时,通过CR3寄存器可以将其转化为物理地址,但是在虚拟化环境中这个物理地址只是客户机的物理地址,还不是真实内存硬件上的物理地址。所以,虚拟机监控器就需要维护从客户机虚拟地址到宿主机物理地址之间的一个映射关系,在没有硬件提供的内存虚拟化之前,这个维护映射关系的页表叫作影子页表(Shadow Page Table)。内存的访问和更新通常是非常频繁的,要维护影子页表中对应关系会非常复杂,开销也较大。同时需要为每一个客户机都维护一份影子页表,当客户机数量较多时,其影子页表占用的内存较大也会是一个问题。
Intel CPU 在硬件设计上就引入了EPT(Extended Page Tables,扩展页表),从而将客户机虚拟地址到宿主机物理地址的转换通过硬件来实现。当然,这个转换是通过两个步骤来实现的,如图2-3所示。首先,通过客户机CR3寄存器将客户机虚拟地址转化为客户机物理地址,然后通过查询EPT来实现客户机物理地址到宿主机物理地址的转化。EPT的控制权在虚拟机监控器中,只有当CPU工作在非根模式时才参与内存地址的转换。使用EPT后,客户机在读写CR3和执行INVLPG指令时不会导致VM Exit,而且客户页表结构自身导致的页故障也不会导致VM Exit。所以通过引入硬件上EPT的支持,简化了内存虚拟化的实现复杂度,同时也提高了内存地址转换的效率。
除了EPT,Intel在内存虚拟化效率方面还引入了VPID(Virtual-processor identifier)特性,在硬件级对TLB资源管理进行了优化。在没有VPID之前,不同客户机的逻辑CPU在切换执行时需要刷新TLB,而TLB的刷新会让内存访问的效率下降。VPID技术通过在硬件上为TLB增加一个标志,可以识别不同的虚拟处理器的地址空间,所以系统可以区分虚拟机监控器和不同虚拟机上不同处理器的TLB,在逻辑CPU切换执行时就不会刷新TLB,而只需要使用对应的TLB即可。VPID的示意图如图2-4所示。当CPU运行在非根模式下,且虚拟机执行控制寄存器的“enable VPID”比特位被置为1时,当前的VPID的值是VMCS中的VPID执行控制域的值,其值是非0的。VPID的值在3种情况下为0,第1种是在非虚拟化环境中执行时,第2种是在根模式下执行时,第3种情况是在非根模式下执行但“enable VPID”控制位被置0时。
2.1.3 I/O虚拟化
在虚拟化的架构下,虚拟机监控器必须支持来自客户机的I/O请求。通常情况下有以下4种I/O虚拟化方式。
1)设备模拟:在虚拟机监控器中模拟一个传统的I/O设备的特性,比如在QEMU中模拟一个Intel的千兆网卡或者一个IDE硬盘驱动器,在客户机中就暴露为对应的硬件设备。客户机中的I/O请求都由虚拟机监控器捕获并模拟执行后返回给客户机。
2)前后端驱动接口:在虚拟机监控器与客户机之间定义一种全新的适合于虚拟化环境的交互接口,比如常见的virtio协议就是在客户机中暴露为virtio-net、virtio-blk等网络和磁盘设备,在QEMU中实现相应的virtio后端驱动。
3)设备直接分配:将一个物理设备,如一个网卡或硬盘驱动器直接分配给客户机使用,这种情况下I/O请求的链路中很少需要或基本不需要虚拟机监控器的参与,所以性能很好。
4)设备共享分配:其实是设备直接分配方式的一个扩展。在这种模式下,一个(具有特定特性的)物理设备可以支持多个虚拟机功能接口,可以将虚拟功能接口独立地分配给不同的客户机使用。如SR-IOV就是这种方式的一个标准协议。
表2-1展示了这4种I/O虚拟化方式的优缺点,给读者一个概括性的认识。在这4种方式中,前两种都是纯软件的实现,后两种都需要特定硬件特性的支持。
设备直接分配在Intel平台上就是VT-d(Virtualization Technology For Directed I/O)特性,一般在系统BIOS中可以看到相关的参数设置。Intel VT-d为虚拟机监控器提供了几个重要的能力:I/O设备分配、DMA重定向、中断重定向、中断投递等。图2-5描述了在VT-d硬件特性的帮助下实现的设备直接分配的架构,并与最传统的、通过软件模拟设备的I/O设备虚拟化进行了对比。
尽管VT-d特性支持的设备直接分配方式性能可以接近物理设备在非虚拟化环境中的性能极限,但是它有一个缺点:单个设备只能分配给一个客户机,而在虚拟化环境下一个宿主机上往往运行着多个客户机,很难保证每个客户机都能得到一个直接分配的设备。为了克服这个缺点,设备共享分配硬件技术就应运而生,其中SR-IOV(Single Root I/O Virtualization and Sharing)就是这样的一个标准。实现了SR-IOV规范的设备,有一个功能完整的PCI-e设备成为物理功能(Physical Function,PF)。在使能了SR-IOV之后,PF就会派生出若干个虚拟功能(Virtual Function,VF)。VF看起来依然是一个PCI-e设备,它拥有最小化的资源配置,有用独立的资源,可以作为独立的设备直接分配给客户机使用。Intel的很多高级网卡如82599系列网卡就支持SR-IOV特性,一个85299网卡PF就即可配置出多达63个VF,基本可满足单个宿主机上的客户机分配使用。当然,SR-IOV这种特性可以看作VT-d的一个特殊例子,所以SR-IOV除了设备本身要支持该特性,同时也需要硬件平台打开VT-d特性支持。图2-6展示了一个Intel以太网卡支持SR-IOV的硬件基础架构。
2.1.4 Intel虚拟化技术发展
虚拟化技术从最初的纯软件的虚拟化技术,逐步发展到硬件虚拟化技术的支持,时至今日硬件虚拟化技术已比较成熟。前面3小节已经分别就各种硬件虚拟化技术进行了介绍,这里以Intel平台为例,再对其做一个小结。
Intel硬件虚拟化技术大致分为如下3个类别(这个顺序也基本上是相应技术出现的时间先后顺序)。
1)VT-x技术:是指Intel处理器中进行的一些虚拟化技术支持,包括CPU中引入的最基础的VMX技术,使得KVM等硬件虚拟化基础的出现成为可能。同时也包括内存虚拟化的硬件支持EPT、VPID等技术。
2)VT-d技术:是指Intel的芯片组的虚拟化技术支持,通过Intel IOMMU可以实现对设备直接分配的支持。
3)VT-c技术:是指Intel的I/O设备相关的虚拟化技术支持,主要包含两个技术:一个是借助虚拟机设备队列(VMDq)最大限度提高 I/O 吞吐率,VMDq由Intel网卡中的专用硬件来完成;另一个是借助虚拟机直接互连(VMDc)大幅提升虚拟化性能,VMDc主要就是基于SR-IOV标准将单个Intel网卡产生多个VF设备,用来直接分配给客户机。
图2-7展示了Intel的硬件虚拟化技术的发展线路图,从中我们可以看到从2005年开始支持VT-x硬件虚拟化,到现在较多的SR-IOV等VT-d的虚拟化技术,硬件虚拟化技术家族有了越来越多的成员,技术特性也逐步完善。如何在具体业务的生产环境中充分利用硬件虚拟化技术带来的技术红利,构建高性能、可扩展、易维护的虚拟化环境,可能是大家学习虚拟化的一个主要目标。通过本书,希望大家也能够了解一些实践经验和受到一些启发。
2.2 KVM架构概述
上一节介绍了CPU、内存、I/O等硬件虚拟化技术。KVM就是在硬件辅助虚拟化技术之上构建起来的虚拟机监控器。当然,并非要所有这些硬件虚拟化都支持才能运行KVM虚拟化,KVM对硬件最低的依赖是CPU的硬件虚拟化支持,比如:Intel的VT技术和AMD的AMD-V技术,而其他的内存和I/O的硬件虚拟化支持,会让整个KVM虚拟化下的性能得到更多的提升。
KVM虚拟化的核心主要由以下两个模块组成:
1)KVM内核模块,它属于标准Linux内核的一部分,是一个专门提供虚拟化功能的模块,主要负责CPU和内存的虚拟化,包括:客户机的创建、虚拟内存的分配、CPU执行模式的切换、vCPU寄存器的访问、vCPU的执行。
2)QEMU用户态工具,它是一个普通的Linux进程,为客户机提供设备模拟的功能,包括模拟BIOS、PCI/PCIE总线、磁盘、网卡、显卡、声卡、键盘、鼠标等。同时它通过ioctl系统调用与内核态的KVM模块进行交互。
KVM是在硬件虚拟化支持下的完全虚拟化技术,所以它能支持在相应硬件上能运行的几乎所有的操作系统,如:Linux、Windows、FreeBSD、MacOS等。KVM的基础架构如图2-8所示。在KVM虚拟化架构下,每个客户机就是一个QEMU进程,在一个宿主机上有多少个虚拟机就会有多少个QEMU进程;客户机中的每一个虚拟CPU对应QEMU进程中的一个执行线程;一个宿主机中只有一个KVM内核模块,所有客户机都与这个内核模块进行交互。
2.3 KVM内核模块
KVM内核模块是标准Linux内核的一部分,由于KVM的存在让Linux本身就变成了一个Hypervisor,可以原生地支持虚拟化功能。目前,KVM支持多种处理器平台,它支持最常见的以Intel和AMD为代表的x86和x86_64平台,也支持PowerPC、S/390、ARM等非x86架构的平台。
KVM模块是KVM虚拟化的核心模块,它在内核中由两部分组成:一个是处理器架构无关的部分,用lsmod命令中可以看到,叫作kvm模块;另一个是处理器架构相关的部分,在Intel平台上就是kvm_intel这个内核模块。KVM的主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚拟客户机的运行提供一定的支持。
KVM仅支持硬件辅助的虚拟化,所以打开并初始化系统硬件以支持虚拟机的运行,是KVM模块的职责所在。以KVM在Intel公司的CPU上运行为例,在被内核加载的时候,KVM模块会先初始化内部的数据结构;做好准备之后,KVM模块检测系统当前的CPU,然后打开CPU控制寄存器CR4中的虚拟化模式开关,并通过执行VMXON指令将宿主操作系统(包括KVM模块本身)置于CPU执行模式的虚拟化模式中的根模式;最后,KVM模块创建特殊设备文件 /dev/kvm 并等待来自用户空间的命令。接下来,虚拟机的创建和运行将是一个用户空间的应用程序(QEMU)和KVM模块相互配合的过程。
/dev/kvm 这个设备可以被当作一个标准的字符设备,KVM模块与用户空间QEMU的通信接口主要是一系列针对这个特殊设备文件的loctl调用。当然,每个虚拟客户机针对/dev/kvm文件的最重要的loctl调用就是“创建虚拟机”。在这里,“创建虚拟机”可以理解成KVM为了某个特定的虚拟客户机(用户空间程序创建并初始化)创建对应的内核数据结构。同时,KVM还会返回一个文件句柄来代表所创建的虚拟机。针对该文件句柄的loctl调用可以对虚拟机做相应的管理,比如创建用户空间虚拟地址和客户机物理地址及真实内存物理地址的映射关系,再比如创建多个可供运行的虚拟处理器(vCPU)。同样,KVM模块会为每一个创建出来的虚拟处理器生成对应的文件句柄,对虚拟处理器相应的文件句柄进行相应的loctl调用,就可以对虚拟处理器进行管理。
针对虚拟处理器的最重要的loctl调用就是“执行虚拟处理器”。通过它,用户空间准备好的虚拟机在KVM模块的支持下,被置于虚拟化模式中的非根模式下,开始执行二进制指令。在非根模式下,所有敏感的二进制指令都会被处理器捕捉到,处理器在保存现场之后自动切换到根模式,由KVM决定如何进一步处理(要么由KVM模块直接处理,要么返回用户空间交由用户空间程序处理)。
除了处理器的虚拟化,内存虚拟化也是由KVM模块实现的,包括前面提到的使用硬件提供的EPT特性,通过两级转换实现客户机虚拟地址到宿主机物理地址之间的转换。
处理器对设备的访问主要是通过I/O指令和MMIO,其中I/O指令会被处理器直接截获,MMIO会通过配置内存虚拟化来捕捉。但是,外设的模拟一般不由KVM模块负责。一般来说,只有对性能要求比较高的虚拟设备才会由KVM内核模块来直接负责,比如虚拟中断控制器和虚拟时钟,这样可以大量减少处理器模式切换的开销。而大部分的输入输出设备交给下一节将要介绍的用户态程序QEMU来负责。
2.4 QEMU用户态设备模拟
QEMU原本就是一个著名的开源虚拟机软件项目,而不是KVM虚拟化软件的一部分。与KVM不同,QEMU最初实现的虚拟机是一个纯软件的实现,通过二进制翻译来实现虚拟化客户机中的CPU指令模拟,所以性能比较低。但是,其优点是跨平台,QEMU支持在Linux、Windows、FreeBSD、Solaris、MacOS等多种操作系统上运行,能支持在QEMU本身编译运行的平台上就实现虚拟机的功能,甚至可以支持客户机与宿主机并不是同一个架构(比如在x86平台上运行ARM客户机)。作为一个存在已久的虚拟机监控器软件,QEMU的代码中有完整的虚拟机实现,包括处理器虚拟化、内存虚拟化,以及KVM也会用到的虚拟设备模拟(比如网卡、显卡、存储控制器和硬盘等)。
除了二进制翻译的方式,QEMU也能与基于硬件虚拟化的Xen、KVM结合,为它们提供客户机的设备模拟。通过与KVM的密切结合,让虚拟化的性能提升得非常高,在真实的企业级虚拟化场景中发挥重要作用,所以我们通常提及KVM虚拟化时就会说“QEMU/KVM”这样的软件栈。
最早期的KVM开发者们为了简化软件架构和代码重用,根据KVM特性在QEMU的基础上进行了修改(当然这部分修改已经合并回QEMU的主干代码,故现在的QEMU已原生支持KVM虚拟化特性)。从图2-8可以看出,每一个虚拟客户机在宿主机中就体现为一个QEMU进程,而客户机的每一个虚拟CPU就是一个QEMU线程。虚拟机运行期间,QEMU会通过KVM模块提供的系统调用进入内核,由KVM 模块负责将虚拟机置于处理器的特殊模式下运行。遇到虚拟机进行I/O操作时,KVM模块会从上次的系统调用出口处返回QEMU,由QEMU来负责解析和模拟这些设备。
从QEMU角度来看,也可以说QEMU使用了KVM模块的虚拟化功能,为自己的虚拟机提供硬件虚拟化的加速,从而极大地提高了虚拟机的性能。除此之外,虚拟机的配置和创建,虚拟机运行依赖的虚拟设备,虚拟机运行时的用户操作环境和交互,以及一些针对虚拟机的特殊技术(如:动态迁移),都是由QEMU自己实现的。
QEMU除了提供完全模拟的设备(如:e1000网卡、IDE磁盘等)以外,还支持virtio协议的设备模拟。virtio是一个沟通客户机前端设备与宿主机上设备后端模拟的比较高性能的协议,在前端客户机中需要安装相应的virtio-blk、virtio-scsi、virtio-net等驱动,而QEMU就实现了virtio的虚拟化后端。QEMU还提供了叫作virtio-blk-data-plane的一种高性能的块设备I/O方式,它最初在QEMU 1.4版本中被引入。virtio-blk-data-plane与传统virtio-blk相比,它为每个块设备单独分配一个线程用于I/O处理,data-plane线程不需要与原QEMU执行线程同步和竞争锁,而且它使用 ioeventfd/irqfd 机制,同时利用宿主机Linux上的AIO(异步I/O)来处理客户机的I/O请求,使得块设备I/O效率进一步提高。
总之,QEMU既是一个功能完整的虚拟机监控器,也在QEMU/KVM的软件栈中承担设备模拟的工作。
2.5 与QEMU/KVM结合的组件
在KVM虚拟化的软件栈中,毋庸置疑的是KVM内核模块与QEMU用户态程序是处于最核心的位置,有了它们就可通过qemu命令行操作实现完整的虚拟机功能,本书中多数的实践范例正是通过qemu命令行来演示的。然而,在实际的云计算的虚拟化场景中,为了更高的性能或者管理的方便性,还有很多的软件可以作为KVM虚拟化实施中的组件,这里简单介绍其中的几个。
1. vhost-net
vhost-net是Linux内核中的一个模块,它用于替代QEMU中的virtio-net用户态的virtio网络的后端实现。使用vhost-net时,还支持网卡的多队列,整体来说会让网络性能得到较大提高。在6.1.6节中对vhost-net有更多的介绍。
2. Open vSwitch
Open vSwitch是一个高质量的、多层虚拟交换机,使用开源Apache2.0许可协议,主要用可移植性强的C语言编写的。它的目的是让大规模网络自动化可以通过编程扩展,同时仍然支持标准的管理接口和协议(例如NetFlow、sFlow、SPAN、RSPAN、CLI、LACP、802.1ag)。同时也提供了对 OpenFlow 协议的支持,用户可以使用任何支持 OpenFlow 协议的控制器对 OVS 进行远程管理控制。Open vSwitch被设计为支持跨越多个物理服务器的分布式环境,类似于VMware的vNetwork分布式vswitch或Cisco Nexus 1000 V。Open vSwitch支持多种虚拟化技术,包括Xen/XenServer、KVM和VirtualBox。在KVM虚拟化中,要实现软件定义网络(SDN),那么Open vSwitch是一个非常好的开源选择。
3. DPDK
DPDK全称是Data Plane Development Kit,最初是由Intel公司维护的数据平面开发工具集,为Intel x86处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持,现在也是一个完全独立的开源项目,它还支持POWER和ARM处理器架构。不同于Linux系统以通用性设计为目的,它专注于网络应用中数据包的高性能处理。具体体现在DPDK应用程序是运行在用户空间上,利用自身提供的数据平面库来收发数据包,绕过了Linux内核协议栈对数据包处理过程。其优点是:性能高、用户态开发、出故障后易恢复。在KVM架构中,为了达到非常高的网络处理能力(特别是小包处理能力),可以选择DPDK与QEMU中的vhost-user结合起来使用。
4. SPDK
SPDK全称是Storage Performance Development Kit,它可为编写高性能、可扩展的、用户模式的存储程序提供一系列工具及开发库。它与DPDK非常类似,其主要特点是:将驱动放到用户态从而实现零拷贝、用轮询模式替代传统的中断模式、在所有的I/O链路上实现无锁设计,这些设计会使其性能比较高。在KVM中需要非常高的存储I/O性能时,可以将QEMU与SPDK结合使用。
5. Ceph
Ceph是Linux上一个著名的分布式存储系统,能够在维护 POSIX 兼容性的同时加入复制和容错功能。Ceph由储存管理器(Object storage cluster对象存储集群,即OSD守护进程)、集群监视器(Ceph Monitor)和元数据服务器(Metadata server cluster,MDS)构成。其中,元数据服务器MDS仅仅在客户端通过文件系统方式使用Ceph时才需要。当客户端通过块设备或对象存储使用Ceph时,可以没有MDS。Ceph支持3种调用接口:对象存储,块存储,文件系统挂载。在libvirt和QEMU中都有Ceph的接口,所以Ceph与KVM虚拟化集成是非常容易的。在OpenStack的云平台解决方案中,Ceph是一个非常常用的存储后端。
6. libguestfs
libguestfs是用于访问和修改虚拟机的磁盘镜像的一组工具集合。libguestfs提供了访问和编辑客户机中的文件、脚本化修改客户机中的信息、监控磁盘使用和空闲的统计信息、P2V、V2V、创建客户机、克隆客户机、备份磁盘内容、格式化磁盘、调整磁盘大小等非常丰富的功能。libguestfs还提供了共享库,可以在C/C++、Python等编程语言中对其进行调用。libguestfs不需要启动KVM客户机就可以对磁盘镜像进行管理,功能强大且非常灵活,是管理KVM磁盘镜像的首选工具。
2.6 KVM上层管理工具
一个成熟的虚拟化解决方案离不开良好的管理和运维工具,部署、运维、管理的复杂度与灵活性是企业实施虚拟化时重点考虑的问题。KVM目前已经有从libvirt API、virsh命令行工具到OpenStack云管理平台等一整套管理工具,尽管与老牌虚拟化巨头VMware提供的商业化虚拟化管理工具相比在功能和易用性上有所差距,但KVM这一整套管理工具都是API化的、开源的,在使用的灵活性以及对其做二次开发的定制化方面仍有一定优势。根据笔者的实践经验,本节给大家概括性地介绍KVM软件栈中常见的几个管理运维工具,在第4章将会详细介绍相关内容。
1. libvirt
libvirt是使用最广泛的对KVM虚拟化进行管理的工具和应用程序接口,已经是事实上的虚拟化接口标准,本节后部分介绍的其他工具都是基于libvirt的API来实现的。作为通用的虚拟化API,libvirt不但能管理KVM,还能管理VMware、Hyper-V、Xen、VirtualBox等其他虚拟化方案。
2. virsh
virsh是一个常用的管理KVM虚拟化的命令行工具,对于系统管理员在单个宿主机上进行运维操作,virsh命令行可能是最佳选择。virsh是用C语言编写的一个使用libvirt API 的虚拟化管理工具,其源代码也是在libvirt这个开源项目中的。
3. virt-manager
virt-manager是专门针对虚拟机的图形化管理软件,底层与虚拟化交互的部分仍然是调用libvirt API来操作的。virt-manager除了提供虚拟机生命周期(包括:创建、启动、停止、打快照、动态迁移等)管理的基本功能,还提供性能和资源使用率的监控,同时内置了VNC和SPICE客户端,方便图形化连接到虚拟客户机中。virt-manager在RHEL、CentOS、Fedora等操作系统上是非常流行的虚拟化管理软件,在管理的机器数量规模较小时,virt-manager是很好的选择。因其图形化操作的易用性,成为新手入门学习虚拟化操作的首选管理软件。
4. OpenStack
OpenStack是一个开源的基础架构即服务(IaaS)云计算管理平台,可用于构建共有云和私有云服务的基础设施。OpenStack是目前业界使用最广泛的功能最强大的云管理平台,它不仅提供了管理虚拟机的丰富功能,还有非常多其他重要管理功能,如:对象存储、块存储、网络、镜像、身份验证、编排服务、控制面板等。OpenStack仍然使用libvirt API来完成对底层虚拟化的管理。
2.7 本章小结
本节主要介绍了KVM虚拟化的基本原理,从硬件到软件、从底层到上层都做了一些介绍,包括:硬件虚拟化技术简介、KVM软件架构概况、KVM内核模块、QEMU用户态设备模拟、与KVM结合的vhost-net等组件、KVM的管理工具等。由于KVM是基于硬件辅助的虚拟化软件,故在2.1节又分别介绍了CPU虚拟化、内存虚拟化、I/O虚拟化以及Intel的虚拟化技术发展情况,以帮助读者理解虚拟化原理。同时,通过对QEMU/KVM相结合的组件和KVM上层管理工具的介绍,让读者在实施KVM虚拟化之前有概括性的认识,对于提高虚拟化的性能和提供工程实施效率都会有所帮助。