QEMU、KVM和Virsh的区别
概念
QEMU
QEMU(Quick Emulator)是一个免费的开源模拟器。它通过动态二进制转换模拟机器的处理器,并为机器提供一组不同的硬件和设备模型,使其能够运行各种客户操作系统。它可以与基于内核的虚拟机(KVM)进行互操作,以接近本地速度运行虚拟机。QEMU还可以对用户级进程进行仿真,允许为一种架构编译的应用程序在另一种架构上运行。
KVM
基于内核的虚拟机(KVM)是Linux内核中的一个免费开源虚拟化模块,允许内核充当虚拟机监控程序。KVM需要一个具有硬件虚拟化扩展的处理器,如Intel VT
或AMD-V
。
Virsh
libvirt
是一个开源API、守护进程和管理工具,用于管理平台虚拟化。可用于管理KVM、Xen、VMware ESXi、QEMU等虚拟化技术。在基于云的解决方案的开发中,这些API被广泛用于管理程序的编排层。
区别
QEMU,其中关键字emu,全称emulator,模拟器,所以单纯使用QEMU是采用的完全虚拟化的模式。
QEMU向Guest OS模拟CPU,也模拟其他的硬件,Guest OS认为自己和硬件直接打交道,其实是同QEMU模拟出来的硬件打交道,QEMU将这些指令转译给真正的硬件。由于所有的指令都需要使用QEMU进行recompiler
,因而性能相对较差。但由于存在recompiler
,所以QEMU可以跨架构运行程序。
由于完全虚拟化是非常慢的,所以必须要使用硬件辅助虚拟化技术例如Intel-VT
,AMD-V
,所以需要CPU硬件开启这个标志位,一般在BIOS里面设置。查看是否开启。
grep "vmx" /proc/cpuinfo # 应用于 Intel CPU
grep "svm" /proc/cpuinfo # 应用于 AMD CPU
当开始了标志位之后,通过KVM,Guest OS的CPU指令不用经过QEMU转译,而是在CPU直接运行,大大提高了速度。
所以KVM在内核里面需要有一个模块,来设置当前CPU是Guest OS在用,还是Host OS在用。QEMU将KVM整合进来,通过ioctl
调用/dev/kvm
接口,将有关CPU指令的部分交由内核模块来做,就是QEMU-kvm
(QEMU-system-XXX)。如果需要进行网络和存储访问,则通过类虚拟化或者直通Pass through
的方式,通过加载特殊的驱动,加速访问网络和存储资源。
此外QEMU还会模拟其他的硬件,如Network, Disk,同样全虚拟化的方式也会影响这些设备的性能。 于是QEMU采取半虚拟化或者类虚拟化的方式,让Guest OS加载特殊的驱动来做这件事情。
例如网络需要加载virtio_net
,存储需要加载virtio_blk
,Guest需要安装这些半虚拟化驱动,Guest OS知道自己是虚拟机,所以数据直接发送给半虚拟化设备,经过特殊处理,例如排队,缓存,批量处理等性能优化方式,最终发送给真正的硬件,一定程度上提高了性能。
然而直接用QEMU或者QEMU-kvm或者QEMU-system-xxx的很少,大多数人还是通过virsh
启动,virsh
属于libvirt
工具,libvirt
是目前使用最为广泛的对KVM虚拟机进行管理的工具和API,但是这个工具不止可以管理KVM。还支持很多其他的虚拟化方案。
Libvirt分服务端和客户端,Libvirtd是一个daemon进程,是服务端,可以被本地的virsh调用,也可以被远程的virsh调用,virsh相当于客户端。
Libvirtd调用QEMU-kvm操作虚拟机,有关CPU虚拟化的部分,QEMU-kvm调用kvm的内核模块来实现
总结
总的来说,QEMU是模拟处理器和外围设备的最低级别。 如果 CPU 启用了 VT,KVM 将对其进行加速。而Libvirt 提供了一个守护进程和客户端来操作虚拟机。