QEMU
QEMU是一个模拟器,通过动态二进制转换来模拟cpu以及其他一系列硬件,让guest os认为自己就是在和真正的硬件打交道
,其实是和qemu模拟的硬件交互。这种模式下,guest os可以和主机上的硬件进行交互,但是所有的指令都需要qemu来进行翻译,性能会比较差。
KVM
KVM是Linux内核提供的虚拟化架构,它需要硬件CPU支持,比如采用硬件辅助虚拟化的Intel-VT
,AMD-V
。
KVM通过一个内核模块kvm.ko
来实现核心虚拟化功能,以及一个和处理器相关的模块,如kvm-intel.ko
或者kvm-amd.ko
。
kvm本身不实现模拟,仅暴露一个接口/dev/kvm
,用户态程序可以通过访问这个接口的ioctl函数
来实现vcpu的创建,和虚拟内存的地址空间分配。
有了kvm之后,guest-os的CPU指令不用再经过qemu翻译就可以运行,大大提升了运行速度。
但是kvm只能模拟cpu和内存,不能模拟其他设备,于是就有了下面这个两者合一的技术qemu-kvm
。
QEMU-KVM
qemu-kvm,是qemu一个特定于kvm加速模块的分支。
qemu 将 kvm整合进来,通过ioctl
调用/dev/kvm
,将cpu相关的指令交给内核模块来做,kvm只实现了cpu和内存虚拟化,但不能模拟其它设备,因此qemu还需要模拟其它设备(如:硬盘、网卡等),qemu加上kvm就是完整意义上的服务器虚拟化。
综上所述,QEMU-KVM具有两大作用:
- 提供对cpu,内存(KVM负责),IO设备(QEMU负责)的虚拟
- 对各种虚拟设备的创建,调用进行管理(QEMU负责)
qemu-kvm架构如下:
Libvirtd
Libvirtd是目前使用最广泛的对kvm虚拟机进行管理的工具和api。Libvirtd是一个Domain进程
可以被本地virsh调用,也可以被远端的virsh
调用,libvirtd调用kvm-qemu
控制虚拟机。
libvirtd由几个不同的部分组成,其中包括应用程序编程接口(API)库,一个守护进程(libvirtd)和一个默认的命令行工具(virsh),libvirtd守护进程负责对虚拟机的管理,因此要确保这个进程的运行。
总结
kvm是最底层的VMM,它可以模拟cpu和内存,但是缺少对网络、I/O及周边设备的支持,因此不能直接使用。
qemu-kvm是构建与kvm之上的,它提供了完整的虚拟化方案。
openstack(nova)的核心功能就是管理一大堆虚拟机,虚拟机可以是各种各样(kvm, qemu, xen, vmware...),而且管理的方法也可以是各种各样(libvirt, xenapi, vmwareapi...)。而nova中默认使用的管理虚拟机的API就是libvirtd。
简单说就是,openstack不会去直接控制qemu-kvm,而是通过libvirtd库去间接控制qemu-kvm。
另外,libvirt还提供了跨VM平台的功能,它可以控制除了QEMU之外的模拟器,包括vmware, virtualbox, xen等等。所以为了openstack的跨VM性,所以openstack只会用libvirt而不直接用qemu-kvm。