本篇将会讲到:

1. KVM
2. QEMU
3. KVM 与 QEMU 之间的关系

好了,以上的内容可能会不按顺序讲,可能会突然就讲完了

(这一篇的技术含量比较高,我会尽量讲的通俗一点)而且这一篇不太可能会出现图片了

首先,你需要知道什么是虚拟化?

1

虚拟化

用通俗的话来说,虚拟化使得在一台真正存在的电脑(后面我们都称作物理机)上可以跑多台虚拟机

虚拟机共享物理机的 CPU、内存、i/o 硬件资源。但是从逻辑上与虚拟机之间是相互隔离的

(共享目录并不代表就不相互隔离,共享目录是一个附加内容,并非虚拟化本身带有的)

物理机我们一般称为宿主机(Host),宿主机上面的虚拟机称为客户机(Guest)。

那么

1.1

Host 是如何将自己的硬件资源虚拟化,并提供给 Guest 使用的呢?

这个主要是通过一个叫做 Hypervisor 的程序实现的。也就是系统管理程序

虚拟化又分为两种:1 类虚拟化和2 类虚拟化

他们之前的差异只是 Hypervisor 的实现方式和所处的位置不同而已。

1.2

1 类虚拟化

Hypervisor 是直接安装在物理机上,多个虚拟机在 Hypervisor 上运行。而这一类 Hypervisor 实现方式一般是一个特殊定制的 Linux 系统。Xen 和 VMWare 的 ESXi 都属于这个类型。

1.3

2 类虚拟化

物理机上首先是安装了常规的操作系统,比如 macOS、Ubuntu 和 Windows。这个时候,Hypervisor 将会作为 OS 上的一个程序模块运行,并对管理虚拟机进行管理。KVM、VirtualBox 和 VMWare Workstation 都属于这个类型

1.4

理论上讲:

1 类虚拟化一般对硬件虚拟化功能进行了特别优化,性能上比 2 型要高;

2 类虚拟化因为基于普通的操作系统,会比较灵活,比如支持虚拟机嵌套。嵌套意味着可以在 KVM 虚拟机中再运行 KVM(简称套娃)

Qemu与KVM的关系与区别 qemu kvm 区别_虚拟化


2

KVM

KVM(全称 Kernel-Based Virtual Machines)是一个基于 Linux 内核的虚拟化技术,可以直接将 Linux 内核转换为一个系统的管理程序从而使得 Linux 内核是能够直接管理到虚拟机的。

2.1

而那些虚拟机上的 cpu 是如何虚拟出来的?

就是由原有的内核中的一个线程,通过 kvm 模块辅助完成,比如一个虚拟机的一颗 cpu运行就是通过原有内核中的一个线程通过 kvm 模块辅助在内核中完成,两颗 cpu 就是用两个线程,所以从原有内核的角度来看虚拟 cpu 就是一个线程

2.2

KVM 虚拟机的用户会进行 i/o 调用,是个怎么个过程?

I/O是 input/output 的缩写,即输入输出端口。首先你要知道 i/o 调用一般都是特权指令。首先用户空间,会发起系统调用,将请求转交给自己的内核空间,内核空间再转交给原有的用户空间的QEMU应用程序所模拟出来的各种硬件设备,再由QEMU转交给原有内核空间完成真正的 i/o 系统调用,如果非 i/o 类的特权指令则直接交给硬件 cpu 处理

这一特性使得 KVM 技术性能的损失和真正的物理机相比小于 10%

从这里我们也可以看出来,KVM 是基于QEMU的。

2.3

KVM 的两类组件

1. /dev/kvm:工作于系统管理程序,在用户空间可通过系统调用来完成 VM 创建、启动等功能
功能:创建 VM、为 VM 分配内存、读写 VCPU 的寄存器、向 VCPU 注入中断、运行 VCPU 等等
2. QEMU进程:工作于用户空间,主要用于实现模拟 PC 机的 IO 设备

而 KVM 的管理工具栈有QEMU:qemu-kvm,qemu-img 和libvirt:CLI: virt-install, virsh。

我这里就说到了 QEMU 了,

QEMU 主要为 KVM 提供了以下几个部分:

  1. 处理器模拟器
  2. 仿真 IO 设备
  3. 关联模拟的设备至真实设备;
  4. 调试器
  5. 与模拟器交互的用户接口

而就QEMU是怎么样的呢?

3

QEMU

QEMU 也是一个虚拟化技术,QEMU 是纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备,我们最熟悉的就是能够模拟一台能够独立运行操作系统的虚拟机,虚拟机认为自己和硬件打交道,但其实是和 QEMU 模拟出来的硬件打交道,QEMU 将这些指令转译给真正的硬件。

Bochs,PearPC 等与其类似,但是不具备 QEMU 的许多特性,比如说高速度及跨平台的特性

QEMU 通过 KQEMU 这个闭源的加速器,让 QEMU 能模拟至接近真实电脑的速度。

特别注意!此处非 QEMU 原生!

正因为 QEMU 是纯软件实现的,所有的指令都要经 QEMU 过一手,性能非常低,所以,在生产环境中,大多数的做法都是配合 KVM 来完成虚拟化工作,因为 KVM 是硬件辅助的虚拟化技术,主要负责比较繁琐的 CPU 和内存虚拟化,而 QEMU 则负责 I/O 虚拟化,两者合作各自发挥自身的优势,相得益彰

而这,就是QEMU 与 KVM 之间的联系

QEMU 软件虚拟化实现的思路是采用二进制指令翻译技术,主要是提取 guest 代码,然后将其翻译成 TCG 中间代码,最后再将中间代码翻译成 host 指定架构的代码,如 x86 体系就翻译成其支持的代码形式,ARM 架构同理。

3.1

QEMU 的源码结构

从宏观上看,源码结构主要包含以下几个部分:

  • /vl.c:最主要的模拟循环,虚拟机环境初始化,和 CPU 的执行。
  • /target-arch/translate.c:将 guest 代码翻译成不同架构的 TCG 操作码。
  • /tcg/tcg.c:主要的 TCG 代码。
  • /tcg/arch/tcg-target.c:将 TCG 代码转化生成主机代码。
  • /cpu-exec.c:主要寻找下一个二进制翻译代码块,如果没有找到就请求得到下一个代码块,并且操作生成的代码块。

总体来说,QEMU 就可以说成是 KVM 的父亲。QEMU 具有非常多的功能比如说:

qemu-img qemu-system-x86_64, arm, ppc 等等 每个选项中又有一大堆的选项,非常细节,-cpu 可以模拟 CPU,-net 可以设置网卡,还可以设置显卡,就是很多啦~

4

与 UTM 的关系

UTM 使用了QEMU 作为内核,并以JIT 代码加速(这是另外一种加速方法)它同样支持自定义参数。由于 iOS 终端的处理器原因,我们无法使用 KVM 硬件虚拟化,除了这个还有 iOS 终端的内存限制,这些导致 UTM 的性能会比我们熟知的 KVM 相差有点大。当然目前 UTM 也在持续研究关于性能提升的方式,