Openstack 本身是一个云平台管理框架,它需要集成许多底层技术来实现云服务的各种功能,今天我们来梳理一下Openstack里最常见的计算服务组合openstack,kvm,qemu,libvirt之间的关系。
QEMU
QEMU 是纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备,我们最熟悉的就是能够模拟一台能够独立运行操作系统的虚拟机,虚拟机认为自己和硬件打交道,但其实是和 QEMU 模拟出来的硬件打交道,QEMU 将这些指令转译给真正的硬件。
正因为 QEMU 是纯软件实现的,所有的指令都要经 QEMU 过一手,性能非常低,所以,在生产环境中,大多数的做法都是配合 KVM 来完成虚拟化工作,因为 KVM 是硬件辅助的虚拟化技术,主要负责 比较繁琐的 CPU 和内存虚拟化,而 QEMU 则负责 I/O 虚拟化,两者合作各自发挥自身的优势,相得益彰。
KVM
KVM 全称是基于内核的虚拟机(Kernel-based Virtual Machine),它是 Linux 的一个内核模块,该内核模块使得 Linux 变成了一个 Hypervisor,是基于虚拟化扩展(Intel VT 或者 AMD-V)的 X86 硬件的开源的 Linux 原生的全虚拟化解决方案。它是Linux的一个很小的模块,利用Linux做大量的事,如任务调度、内存管理与硬件设备交互等。
KVM包含一个内核模块kvm.ko用来实现核心虚拟化功能,以及一个和处理器强相关的模块如kvm-intel.ko或kvm-amd.ko。KVM本身不实现任何模拟,仅仅是暴露了一个/dev/kvm接口,这个接口可被宿主机用来主要负责vCPU的创建,虚拟内存的地址空间分配,vCPU寄存器的读写以及vCPU的运行。有了KVM以后,guest os的CPU指令不用再经过QEMU来转译便可直接运行,大大提高了运行速度。但KVM的kvm.ko本身只提供了CPU和内存的虚拟化,所以它必须结合QEMU才能构成一个完整的虚拟化技术。
QEMU-KVM
从前面的介绍可知道,KVM负责cpu虚拟化+内存虚拟化,实现了cpu和内存的虚拟化,但kvm并不能模拟其他设备,还必须有个运行在用户空间的工具才行。KVM的开发者选择了比较成熟的开源虚拟化软件QEMU来作为这个工具,QEMU模拟IO设备(网卡,磁盘等),对其进行了修改,最后形成了QEMU-KVM。
在QEMU-KVM中,KVM运行在内核空间,QEMU运行在用户空间,实际模拟创建、管理各种虚拟硬件,QEMU将KVM整合了进来,通过/ioctl 调用 dev/kvm,从而将CPU指令的部分交给内核模块来做,KVM实现了CPU和内存的虚拟化,但KVM不能虚拟其他硬件设备,因此qemu还有模拟IO设备(磁盘,网卡,显卡等)的作用,KVM加上QEMU后就是完整意义上的服务器虚拟化。
综上所述,QEMU-KVM具有两大作用:
提供对cpu,内存(KVM负责),IO设备(QEMU负责)的虚拟
对各种虚拟设备的创建,调用进行管理(QEMU负责)
这个方案中,QEMU模拟其他的硬件,如Network, Disk,同样会影响这些设备的性能。于是又产生了pass through半虚拟化设备virtio_blk, virtio_net,提高设备性能。
QEMU-KVM,是QEMU的一个特定于KVM加速模块的分支,里面包含了很多关于KVM的特定代码,与KVM模块一起配合使用。目前QEMU-KVM已经与QEMU合二为一,所有特定于KVM的代码也都合入了QEMU,当需要与KVM模块配合使用的时候,只需要在QEMU命令行加上 --enable-kvm就可以。
Libvirt
Libvirt是用于管理虚拟化平台的开源API,后台程序和管理工具的软件集合,包括一个API库,一个守护进程(Libvirtd),和一个命令行实用程序(virsh)。它可以用于管理KVM、Xen、VMware ESX,QEMU和其他虚拟化技术,为不同的hypervisor提供了统一的管理接口。
openstack, kvm, qemu, libvirt之间的关系
KVM是最底层的hypervisor,用来模拟CPU的运行,但是缺少了对network和周边I/O的支持,所以没法直接使用。
QEMU是一个完整的模拟器,提供了完整的网络和I/O支持。
Libvirt提供了跨VM平台的管理功能,Openstack使用它来控制QEMU,vmware, virtualbox, xen等等虚拟化平台。