序言

私有云的核心之一是虚拟化,KVM是一种x86架构全虚拟化方案,而KVM虚拟化的核心是外设模拟器QEMU(Quick Emulator)和虚拟化管理libvirt库。使用KVM时,我们需要在Linux中载入驱动模块kvm.ko,以及针对Intel/AMD处理器的基础模块kvm_intel.ko或kvm_amd.ko。

QEMU是属于用户空间的模拟器,它可以模拟主流平台诸如x86、PowerPC、ARM、SPARC、OpenRISC等指令集与外设。当QEMU运行在系统模式时,它会模拟出包含CPU、内存等各种外设在内的指定型号机器模型,除此之外,也有很多与主机、客户端的交互选项,比如设备重定向、内存气球、spice USB-Redir等。


KVM是什么?

首先KVM(Kernel Virtual Machine)是Linux的一个内核驱动模块,它能够让Linux主机成为一个Hypervisor(虚拟机监控器)。在支持VMX(Virtual Machine Extension)功能的x86处理器中,Linux在原有的用户模式和内核模式中新增加了客户模式,并且客户模式也拥有自己的内核模式和用户模式,虚拟机就是运行在客户模式中。KVM模块的职责就是打开并初始化VMX功能,提供相应的接口以支持虚拟机的运行。


QEMU是什么?

QEMU(quick emulator)本身并不包含或依赖KVM模块,而是一套由Fabrice Bellard编写的模拟计算机的自由软件。QEMU虚拟机是一个纯软件的实现,可以在没有KVM模块的情况下独立运行,但是性能比较低。QEMU有整套的虚拟机实现,包括处理器虚拟化、内存虚拟化以及I/O设备的虚拟化。QEMU是一个用户空间的进程,需要通过特定的接口才能调用到KVM模块提供的功能。从QEMU角度来看,虚拟机运行期间,QEMU通过KVM模块提供的系统调用接口进行内核设置,由KVM模块负责将虚拟机置于处理器的特殊模式运行。QEMU使用了KVM模块的虚拟化功能,为自己的虚拟机提供硬件虚拟化加速以提高虚拟机的性能。


KVM和QEMU的关系

KVM只模拟CPU和内存,因此一个客户机操作系统可以在宿主机上跑起来,但是你看不到它,无法和它沟通。于是,有人修改了QEMU代码,把他模拟CPU、内存的代码换成KVM,而网卡、显示器等留着,因此QEMU+KVM就成了一个完整的虚拟化平台。

同样KVM只是内核模块,用户并没法直接跟内核模块交互,需要借助用户空间的管理工具,而这个工具就是QEMU。KVM和QEMU相辅相成,QEMU通过KVM达到了硬件虚拟化的速度,而KVM则通过QEMU来模拟设备。对于KVM来说,其匹配的用户空间工具并不仅仅只有QEMU,还有其他的,比如RedHat开发的libvirt、virsh、virt-manager等,QEMU并不是KVM的唯一选择。

所以简单直接的理解就是:QEMU是个计算机模拟器,而KVM为计算机的模拟提供加速功能。

其实,QEMU只是虚拟化实现的模拟器之一,而其它平台比如VMWare、VirtualBox、Citrix等使用的是其专有的模拟器。为了在虚拟化服务器代理中使用统一的API调用hypervior,社区贡献了libvirt虚拟化API库,以管理诸如QEMU/KVM,Xen,VMWare、Microsoft Hyper-V、IBM PowerVM等平台的hypervisor。也可以管理LXC、OpenVZ容器等。与libvirt类似的也有LibCloud、DeltaCloud等开源库,但后者封装的是更高层次的管理平台API,一般用于公私混合或者不同平台混合的云统一管理场景。

那什么又是virtio呢?

virtio 是一种 I/O 半虚拟化解决方案,是一套通用 I/O 设备虚拟化的程序,是对半虚拟化 Hypervisor 中的一组通用 I/O 设备的抽象。提供了一套上层应用与各 Hypervisor 虚拟化设备(KVM,Xen,VMware等)之间的通信框架和编程接口,减少跨平台所带来的兼容性问题,大大提高驱动程序开发效率。

为什么是 virtio

在完全虚拟化的解决方案中,guest VM 要使用底层 host 资源,需要 Hypervisor 来截获所有的请求指令,然后模拟出这些指令的行为,这样势必会带来很多性能上的开销。半虚拟化通过底层硬件辅助的方式,将部分没必要虚拟化的指令通过硬件来完成,Hypervisor 只负责完成部分指令的虚拟化,要做到这点,需要 guest 来配合,guest 完成不同设备的前端驱动程序,Hypervisor 配合 guest 完成相应的后端驱动程序,这样两者之间通过某种交互机制就可以实现高效的虚拟化过程。

由于不同 guest 前端设备其工作逻辑大同小异(如块设备、网络设备、PCI设备、balloon驱动等),单独为每个设备定义一套接口实属没有必要,而且还要考虑扩平台的兼容性问题,另外,不同后端 Hypervisor 的实现方式也大同小异(如KVM、Xen等),这个时候,就需要一套通用框架和标准接口(协议)来完成两者之间的交互过程,virtio 就是这样一套标准,它极大地解决了这些不通用的问题。