Linux虚拟化技术KVM简介 陈岩 161220020
虚拟化技术 虚拟化技术是云计算的基础。 虚拟化使得在一台物理服务器上可以运行多台虚拟机,它们共享物理 机的 CPU、内存、IO 硬件资源,但逻辑上虚拟机之间是相互隔离的。 物理机一般被称为宿主机(Host),宿主机上面的虚拟机称为客户机 (Guest)。 Host主要通过一个叫做 Hypervisor 的程序,将自己的硬件资源虚拟 化,并提供给 Guest 使用。 根据 Hypervisor 的实现方式和所处的位置,虚拟化又分为两种:1型 虚拟化和2型虚拟化。
1型虚拟化 Hypervisor 直接安装在物理机上,多个虚拟机在 Hypervisor 上运行。 Hypervisor 实现方式一般是一个特殊定制的 Linux 系统。Xen 和 VMWare 的 ESXi 都属于这个类型。
2型虚拟化 物理机上安装常规的操作系统,比如 Ubuntu 和 Windows。 Hypervisor 作为 OS 上的一个程序模块运行,并对管理虚拟机进行管 理。KVM、VirtualBox 和 VMWare Workstation 都属于这个类型。
1型与2型的比较 理论上讲: 1型虚拟化一般对硬件虚拟化功能进行了特别优化,性能上比2型要高。 2型虚拟化因为基于普通的操作系统,会比较灵活,比如支持虚拟机 嵌套,即可以在KVM虚拟机中再运行KVM。
KVM基本信息 KVM全称 Kernel-Based Virtual Machine。也就是说 KVM 是基于 Linux 内核实现的。 KVM从 Linux 2.6.20 起就作为一个内核模块被包含在 Linux 内核中。 KVM需要支持虚拟化扩展的 CPU。
KVM实现方式 KVM中包含一个内核加载模块kvm.ko,主要负责两个工作:1.管理虚 拟机的虚拟CPU;2.对虚拟内存进行管理和调度。 KVM 本身不执行任何硬件模拟,需要客户空间程序通过 /dev/kvm 接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的 I/O, 并将它的视频显示映射回宿主的显示屏。目前这个应用程序是 QEMU。 总的来说,KVM作为一个轻量级的Hyperviser,本身只关注虚拟机调 度和内存管理这两个方面。IO 外设的任务交给 Linux 内核和 QEMU。 其实 QEMU 原本不是 KVM 的一部分,它自己就是一个纯软件实现的虚拟化系统,所以其性能低下。但是,QEMU 代码中包含整套的虚拟机实现,包括处理器虚拟化,内存虚拟化,以及 KVM需要使用到的虚拟设备模拟(网卡、显卡、存储控制器和硬盘等)。 为了简化代码,KVM 在 QEMU 的基础上做了修改。VM 运行期间,QEMU 会通过 KVM 模块提供的系统调用进入内核,由 KVM 负责将虚拟机置于处理的特殊模式运行。遇到虚机进行 I/O 操作,KVM 会从上次的系统调用出口处返回 QEMU,由 QEMU 来负责解析和模拟这些设备。
KVM运行框架 Guest:客户机系统,包括CPU(vCPU)、内存、驱动(Console、网卡、I/O 设备驱动等),被 KVM 置于一种受限制的 CPU 模式下运行。 KVM:运行在内核空间,提供CPU 和内存的虚级化,以及客户机的 I/O 拦截。Guest 的 I/O 被 KVM 拦截后,交给 QEMU 处理。 QEMU-KVM:修改过的为 KVM 虚机使用的 QEMU 代码,运行在用户空间,提供硬件 I/O 虚拟化,通过 IOCTL调用和 KVM 交互。 虚机的创建和运行是 QEMU-KVM 和 KVM 相互配合的过程。两者的通信接口主要是一系列针对特殊设备文件 dev/kvm 的 IOCTL 调用。
CPU虚拟化 一个 KVM 虚机在宿主机中其实是一个 qemu-kvm 进程,与其他 Linux 进程一样被调度。 虚机中的每一个虚拟 vCPU 则对应 qemu-kvm 进程中的一个线程。 在这个例子中,宿主机有两个物理 CPU,上面起了两个虚机 VM1 和 VM2。 VM1 有两个 vCPU,VM2 有 4 个 vCPU。可以看到 VM1 和 VM2 分别有两个和 4 个线程在两个物理 CPU 上调度。
从客户机线程到物理 CPU 的两次调度 1. 客户机线程调度到客户机物理CPU 即 KVM vCPU,该调度由客户机 操作系统负责,每个客户机操作系统的实现方式不同。在 KVM 上, vCPU 在客户机系统看起来就像是物理 CPU,因此其调度方法也没有 什么不同。 2. vCPU 线程调度到物理 CPU 即主机物理 CPU,该调度由 Hypervisor 即 Linux 负责。
KVM对vCPU进程的调度 KVM 多数情况下使用标准的 Linux 进程调度方法来调度 vCPU 进程。 每个vCPU都是宿主机中的一个普通的QEMU线程,可以使用taskset工 具对其设置处理器亲和性,使其绑定到某一个或几个固定的CPU上去 调度。 尽管Linux内核的进程调度算法已经非常高效了,在多数情况下不需 要对进程的调度进行干预,不过,在虚拟化环境中有时却有必要对客 户机的QEMU进程或线程绑定到固定的逻辑CPU上。 关于这两次调度,业界有很多的研究,比如上海交大的论文 Schedule Processes, not VCPUs 提出动态地减少 vCPU 的数目即减少第二次调度。
客户机 vCPU 数目的分配方法 不是客户机的 vCPU 越多,其性能就越好,因为线程切换会耗费大量 的时间;应该根据负载需要分配最少的 vCPU。 主机上的客户机的 vCPU 总数不应该超过物理 CPU 内核总数。不超 过的话,就不存在 CPU 竞争,每个 vCPU 线程在一个物理 CPU 核上 被执行;超过的话,会出现部分线程等待 CPU 以及一个 CPU 核上的 线程之间的切换,这时会有 overhead。 将负载分为计算负载和 I/O 负载,对计算负载,需要分配较多的 vCPU,甚至考虑 CPU 亲和性,将指定的物理 CPU 核分给这些客户机。
内存虚拟化 KVM 通过内存虚拟化共享物理系统内存,动态分配给虚拟机。 KVM 需要实现 VA(虚拟内存) -> PA(物理内存) -> MA(机器内存)直接的地址转换。 虚机 OS 控制虚拟地址到客户内存物理地址的映射 (VA -> PA) KVM 需要负责映射客户物理内存到实际机器内存 (PA -> MA)
内存虚拟化通用技术 软件方式:通过软件实现内存地址的翻译,比如 Shadow page table (影子页表)技术。 硬件实现:基于 CPU 的辅助虚拟化功能,比如 AMD 的 NPT 和 Intel 的 EPT 技术 。 NPT (Nested Page Tables) EPT (Extended Page Tables)
KVM内存虚拟化技术 KVM 中,虚机的物理内存即为 qemu-kvm 进程所占用的内存空间。 KVM 使用 CPU 辅助的内存虚拟化方式。 EPT 和 NPT采用类似的原理,都是作为 CPU 中新的一层,用来将客 户机的物理地址翻译为主机的物理地址。 EPT的好处是,VMM不用再保留一份 SPT (Shadow Page Table),并且 不用经过 SPT 这个转换过程。除了降低各个虚拟机器在切换时所造 成的效能损耗外,硬体指令集也比虚拟化软体处理来得可靠与稳定。
Intel EPT官方文档
KSM技术 Kernel SamePage Merging 或 Kernel Shared Memory KSM 作为内核中的守护进程(称为 ksmd)存在,它定期执行页面扫 描,识别副本页面并合并副本,释放这些页面以供它用。 因此,在多个KVM进程中,Linux将内核相似的内存页合并成一个内 存页。 好处:在运行类似的客户机操作系统时,通过 KSM,可以节约大量的 内存,从而可以实现更多的内存超分,运行更多的虚机。 代价:使用KSM技术,会增加内核开销,相当于用时间换空间。
谢谢大家