什么是KVM虚拟化

什么是虚拟化

维基百科关于虚拟化的定义是:“In computing,virtualization refers to the act of creating a virtual(rather than actual)version of something,including virtual computer hardware platforms,storage devices,and computer network resources。”(在计算机领域,虚拟化指 创建某事物的虚拟(而非实际)版本,包括虚拟的计算机硬件平台、存储设备,以及计算 机网络资源)可见,虚拟化是一种资源管理技术,它将计算机的各种实体资源(CPU、内 存、存储、网络等)予以抽象和转化出来,并提供分割、重新组合,以达到最大化利用物 理资源的目的。

 

如图所示的Virtual Machine Monitor(VMM,虚拟机监控器,也称为Hypervisor) 层,就是为了达到虚拟化而引入的一个软件层。它向下掌控实际的物理资源(相当于原本的操作系统);向上呈现给虚拟机N份逻辑的资源。为了做到这一点,就需要将虚拟机对物理资源的访问“偷梁换柱”——截取并重定向,让虚拟机误以为自己是在独享物理资源。虚拟机监控器运行的实际物理环境,称为宿主机;其上虚拟出来的逻辑主机,称为客户机。

软件虚拟化技术

软件虚拟化,顾名思义,就是通过软件模拟来实现VMM层,通过纯软件的环境来模 拟执行客户机里的指令。 最纯粹的软件虚拟化实现当属QEMU。

硬件虚拟化技术

硬件虚拟化技术就是指计算机硬件本身提供能力让客户机指令独立执行,而不需要 (严格来说是不完全需要)VMM截获重定向。

以x86架构为例,它提供一个略微受限制的硬件运行环境供客户机运行,在绝大多数情况下,客户机在此受限环境中运行与原生系统在非虚拟化环境 中运行没有什么两样,不需要像软件虚拟化那样每条指令都先翻译再执行,而VMM运行 在root mode,拥有完整的硬件访问控制权限。仅仅在少数必要的时候,某些客户机指令 的运行才需要被VMM截获并做相应处理,之后客户机返回并继续在non-root mode中运 行。可以想见,硬件虚拟化技术的性能接近于原生系统,并且,极大地简化了VMM的 软件设计架构。

Intel从2005年就开始在其x86 CPU中加入硬件虚拟化的支持——Intel Virtualization Technology,简称Intel VT。到目前为止,在所有的Intel CPU中,都可以看到Intel VT的身 影。并且,每一代新的CPU中,都会有新的关于硬件虚拟化支持、改进的feature加入。也 因如此,Intel x86平台是对虚拟化支持最为成熟的平台

############################################################################### 最理想的虚拟化的两个目标如下:

1)客户机完全不知道自己运行在虚拟化环境中,还以为自己运行在原生环境里。

2)完全不需要VMM介入客户机的运行过程。 纯软件的虚拟化可以做到第一个目标,但性能不是很好,而且软件设计的复杂度大大 增加。

半虚拟化

让客户机意识到自己是运行在虚拟化环境里,并做相应 修改以配合VMM,这就是半虚拟化(Para-Virtualization)。

一方面,可以提升性能和简 化VMM软件复杂度;另一方面,也不需要太依赖硬件虚拟化的支持,从而使得其软件设 计(至少是VMM这一侧)可以跨平台且是优雅的。“本质上,准虚拟化弱化了对虚拟机特 殊指令的被动截获要求,将其转化成客户机操作系统的主动通知。但是,准虚拟化需要修 改客户机操作系统的源代码来实现主动通知。”典型的半虚拟化技术就是virtio,使用virtio 需要在宿主机/VMM和客户机里都相应地装上驱动。

全虚拟化

与半虚拟化相反的,全虚拟化(Full Virtualization)坚持第一个理想化目标:客户机 的操作系统完全不需要改动。敏感指令在操作系统和硬件之间被VMM捕捉处理,客户操 作系统无须修改,所有软件都能在虚拟机中运行。因此,全虚拟化需要模拟出完整的、和 物理平台一模一样的平台给客户机,这在达到了第一个目标的同时也增加了虚拟化层 (VMM)的复杂度。

性能上,2005年硬件虚拟化兴起之前,软件实现的全虚拟化完败于VMM和客户机操 作系统协同运作的半虚拟化,这种情况一直延续到2006年。之后以Intel VT-x、VT-d为 代表的硬件虚拟化技术的兴起,让由硬件虚拟化辅助的全虚拟化全面超过了半虚拟化。但 是,以virtio为代表的半虚拟化技术也一直在演进发展,性能上只是略逊于全虚拟化,加 之其较少的平台依赖性,依然受到广泛的欢迎。

Type1和Type2虚拟化

从软件框架的角度上,根据虚拟化层是直接位于硬件之上还是在一个宿主操作系统之 上,将虚拟化划分为Typel和Type2

Type1(类型1)Hypervisor也叫native或bare-metal Hypervisor。这类虚拟化层直接运 行在硬件之上,没有所谓的宿主机操作系统。它们直接控制硬件资源以及客户机。典型地 如Xen和VMware ESX。

Type2(类型2)Hypervisor运行在一个宿主机操作系统之上,如VMware Workstation;或系统里,如KVM。这类Hypervisor通常就是宿主机操作系统的一个应用程 序,像其他应用程序一样受宿主机操作系统的管理。比如VMware Workstation就是运行在 Windows或者Linux操作系统上的一个程序而已。客户机是在宿主机操作系统上的一个 抽象,通常抽象为进程。

将KVM归为Type1或Type2是有争议的,一方面,它是以kernel module的形式加载于kernel,与kernel融为一体,可以认为它将linux kernel转变为一个Type1的Hyperxisor。另一方面,在逻辑上,它受制于kernel,所有对硬件资源的管理都是通过kernel去做的,所有归为Type2.

KVM简介

KVM全称是Kernel-based Virtual Machine,即基于内核的虚拟机,是采用硬件虚拟化 技术的全虚拟化解决方案

KVM从诞生开始就定位于基于硬件虚拟化支持的全虚拟化实现。它以内核模块的形 式加载之后,就将Linux内核变成了一个Hypervisor,但硬件管理等还是通过Linux kernel 来完成的,所以它是一个典型的Type 2 Hypervisor

一个KVM客户机对应于一个Linux进程,每个vCPU则是这个进程下的一个线程,还 有单独的处理IO的线程,也在一个线程组内。所以,宿主机上各个客户机是由宿主机内 核像调度普通进程一样调度的,即可以通过Linux的各种进程调度的手段来实现不同客户 机的权限限定、优先级等功能。客户机所看到的硬件设备是QUME模拟出来的,当客户机对模拟设备进行操作时,有QUME截获并转换为对实际的物理设备的驱动操作来完成。 KVM依赖linux内核进行内存管理。所以,客户机的物理内存就是宿主机内核管理的普通进程的虚拟内存。进而,linux内存管理的机制,如大页,KSM(内核的同页合并),NUMA(非一致性内存架构),通过mmap的进程间共享内存,统统可以应用到客户机内存管理上。

由于KVM是linux内核的一部分,它可以利用所有领先存储供应商都支持的一种成熟且可靠的存储基础架构。

KVM的原生磁盘格式为QCOW2,它支持快照,允许多级快照,压缩和加密。

KVM支持混合虚拟化,其中半虚拟化的驱动程序安装在客户机操作系统中,允许虚拟机使用优化的I/O接口而不使用模拟的设备,从而为网络和块设备提供高性能的I/O。

内存虚拟化的目的是给虚拟客户机操作系统提供一个从0地址开始的连续物理内存空间,同时在多个客户机之间实现隔离和调度。

Intel CPU在硬件设计上就引入了EPT(扩展页表),从而将客户机虚拟地址到宿主机物理地址的转换通过硬件来实现

VT-c技术:是指Intel的I/O设备相关的虚拟化技术支持,主要包含两个技术:一个是借助虚拟机设备队列(VMDq),最大限度提高I/O吞吐率,VMDq由Intel网卡中的专用硬件来完成;另一个是借助虚拟机之间互连(VMDc)大幅提升虚拟化性能,VMDc主要就是基于SR-IOV标准将单个Intel网卡产生多个VF设备,用来直接分配给客户机。

KVM就是在硬件辅助虚拟化技术之上构建起来的虚拟机监控器。KVM对硬件最低的依赖是CPU的硬件虚拟化支持,

比如:Intel的VT技术和AMD的AMD-V技术,而其他的内存和I/O的硬件虚拟化支持,会让整个KVM虚拟化下的性能得到更多的提升。

KVM内核模块,它属于标准linux内核的一部分,是一个专门提供虚拟化功能的模块,主要负责cpu和内存的虚拟化,包括:客户机的创建,虚拟内存的分配,cpu执行模式的切换,vCPU寄存器的访问,vCPU的执行。

QEMU用户态工具,它是一个普通的linux进程,为客户机提供设备模拟的功能包括模拟BIOS,PCI/PCIE总线,磁盘,网卡,显卡,声卡,键盘,鼠标等。同时它通过ioctl系统调用与内核态的KVM模块进行交互。

KVM是在硬件虚拟化支持下的完全虚拟化技术。

KVM内核模块是标准linux内核的一部分,由于KVM的存在让linux本身就变成了一个Hypervisor,可以原生地支持虚拟化功能,KVM仅支持硬件辅助的虚拟化,所以打开并初始化系统硬件以支持虚拟机的运行,是KVM模块的职责所在。

针对虚拟机处理器的最重要的loctl调用就是“执行虚拟处理器”。通过它,用户空间准备好的虚拟机在KVM模块的支持下,被置于虚拟化模式中的非根模式下,开始执行二进制指令。在非根模式下,所有敏感的二进制都会被处理器捕捉到。处理器在保存现场之后自动切换到根模式,由KVM决定如何进一步处理(要么由KVM模块直接处理,要么返回用户空间交由用户空间程序处理)

虚拟机运行期间,QEMU会通过KVM模块提供的系统调用进入内核,由KVM模块负责将虚拟机置于处理器的特殊模式下运行。遇到虚拟机进行I/O操作时,KVM模块会从上次的系统调用出口处返回QEMU,由QEMU来负责解析和模拟这些设备。

virtio是一个沟通客户机前端设备与宿主机上设备后端模拟的比较高性能的协议,在前端客户机中需要安装相应的virtio-blk, virtio-scsi, virtio-net等驱动,而QEMU就实现了virtio的虚拟化后端。

QEMU既是一个功能完整的虚拟机监控器,也在QEMU/KVM的软件栈中承担设备模拟的工作。

libvirt是使用最广泛的对KVM虚拟化进行管理的工具和应用程序接口,已经是事实上的虚拟化接口标准。

virsh是一个常用的管理KVM虚拟化的命令行工具,对于系统管理员在单个宿主机上进行运维操作,virsh命令行可能是最佳选择。virsh是用c语言编写的一个使用libvirt API的虚拟化管理工具,其源码也是在libvirt这个开源项目中的。

virt-manager是专门针对虚拟机的图形化管理软件,底层与虚拟化交互的部分仍然是调用libvirt API来操作的。virt-mananger除了提供虚拟机生命创建,启动,停止,打快照,动态迁移等管理的基本功能,还提供性能和资源使用率的监控,同时内置了VNC客户端,方便图形化连接到虚拟 客户机中。

KVM是基于内核的虚拟机技术的,要运行KVM虚拟化环境,安装一个linux操作系统的宿主机是必需的。

kvm是作为linux内核中的一个module而存在的,kvm.git是一个包含了最新的kvm模块开发中代码的完整的linux内核源码仓库。它的配置方式与普通的Linux内核配置完全一样,只是需要注意将KVM相关的配置选择为编译内核或者编译为模块。

除了在内核空间的KVM模块之外,在用户空间需要QEMU来模拟所需要的cpu和设备模型,以及启动客户机进程,这样才有了一个完整的KVM运行环境。

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! !   

因为libvirt是目前使用最为广泛的对KVM虚拟机进行管理的工具和应用程序接口,而且一些常用的虚拟机管理工具(如vitsh,virt-install,virt-manager等)。和云计算框架平台(如OpenStack,zstack等)都在底层使用libvirt的应用程序接口。

libvirt作为中间适配层,可以让底层Hypervisor对上层用户空间的管理工具是完全透明的,因为libvirt屏蔽了底层各种Hypervisor的细节,为上层管理工具提供了一个统一的,较稳定的接口(API)。通过libvirt,一些用户空间管理工具可以管理各种不同的Hypervisor和上面运行的客户机。

迁移的概念

迁移包括系统整体的迁移和某个工作负载的迁移。系统整体迁移是将系统上的所有软件(也包括操作系统)完全复制到另一台物理硬件机器之上。而工作负载的迁移,是将系统上的某个工作负载转移到另一台物理机器上继续运行。服务器系统迁移的作用在于简化了系统维护管理,提高了系统负载均衡,增强了系统容错性并优化了系统电源管理。

在虚拟化环境中的迁移,又分为静态迁移,和动态迁移,也有部分人称之为冷迁移和热迁移,或者离线迁移和在线迁移。静态迁移和动态迁移最大的区别就是静态迁移有一段明显时间客户机中的服务不可用,而动态迁移则没有明显的服务暂停时间。虚拟化环境中的静态迁移也可以分为两种,一种是关闭客户机后,将其硬盘镜像复制到另一台宿主机上然后恢复起来,这种迁移不能保留客户机中运行的工作负载;另一种是两台宿主机共享存储系统,只需在暂停(而不是完全关闭)客户机后,复制其内存镜像到另一台宿主机中恢复启动即可,这种迁移可以保持客户机迁移前的内存状态和系统运行的工作负载。

动态迁移是指在保证客户机上应用服务正常运行的同时,让客户机在不同的宿主机之间进行迁移,其逻辑步骤与前面静态迁移几乎一致,有硬盘存储和内存都复制的动态迁移,也有仅复制内存镜像的动态迁移。不同的是,为了保证迁移过程中客户机服务的可用性,迁移过程仅有非常短暂的停机时间。动态迁移允许系统管理员将客户机在不同的物理机上迁移,同时不会断开访问客户机中服务的客户端或应用程序的连接。一个成功的动态迁移需要保证客户机的内存,硬盘存储,网络连接在迁移到目的主机后依然保持不变,而且迁移过程的服务暂停时间较短。

动态迁移的整体迁移时间受诸多因素的影响,如Hypervisor和迁移工具的种类,磁盘存储的大小(如果需要复制磁盘镜像),内存大小及使用率,cpu的性能及利用率,网络带宽大小及是否拥塞等,整体迁移时间一般为几秒到几十分钟不等。动态迁移的服务停机时间也受Hypervisor的种类,内存大小,网络带宽等因素的影响,服务停机时间一般在几毫秒到几百毫秒,而且在终端用户毫无察觉的情况下实现迁移,这种迁移也称为无缝的动态迁移。而静态迁移的服务暂停时间一般都较长,少则几秒钟,多则几分钟,需要依赖于管理员的操作速度和cpu,内存,网络等硬件设备。所以说,静态迁移一般适合于对服务可用性要求不高的场景。而动态迁移的停机时间很短,适合对服务可用性要求较高的场景。动态迁移一般对服务的性能影响不大,这与两台宿主机的硬件配置情况,Hypervisor是否稳定等因素相关。

在KVM中,既支持离线的静态迁移,又支持在线的动态迁移。对于静态迁移,可以在源宿主机上某客户机的QEMU monitor中,用“savevm my_tag”命令来保存一个完整的客户机镜像快照(标记为my_tag),然后在源宿主机中关闭或暂停该客户机。将该客户机的镜像文件复制到另外一台宿主机中,用于源宿主机中启动客户机时以相同的命令启动复制过来的镜像,在其QEMU monitor中用“loadvm my_tag”命令来恢复刚才保存的快照,即可完全加载保存快照时的客户机状态。这里的“savevm”命令保存的完整客户机状态包括cpu状态,内存,设备状态,可写磁盘中的内容。注意,这种保存快照的方法需要qcow2,qed等格式的磁盘镜像文件,因为只有它们才支持快照这个特性。

 

在不考虑磁盘存储复制的情况下(基于共享存储系统),kvm动态迁移的具体迁移过程为:在客户机动态迁移开始后,客户机依然在源宿主机上运行,与此同时,客户机的内存页被传输到目的主机之上。QEMU/kvm会监控并记录下迁移过程中所有已被传输的更改内容。QEMU/KVM也会估计迁移过程中的传输速度,当剩余的内存数据量能够在一个可设定的迁移停机时间(目前QEMU中默认为300毫秒)内传输完成时,QEMU/KVM将会关闭宿主机上的客户机,再将剩余的数据量传输到目的主机上去,最后传输过来的内存内容在目的宿主机上恢复客户机的运行状态。至此,KVM的一个动态迁移操作就完成了。

而当客户机中内存使用量非常大且修改频繁,内存中数据被不断修改的速度大于KVM能够传输的内存速度之时,动态迁移过程是不会完成的,这时要进行迁移只能进行静态迁移。

控制客户机资源的使用--cgroups

在KVM虚拟化环境中,每个客户机操作系统使用系统的一部分物理资源(包括处理 器、内存、磁盘、网络带宽等)。当一个客户机对资源的消耗过大时(特别是QEMU启动 客户机时没有能够控制磁盘或网络I/O的选项),它可能会占用该系统的大部分资源,此 时,其他的客户机对相同资源的请求就会受到严重影响,可能会导致其他客户机响应速度 过慢甚至失去响应。为了让所有客户机都能够按照预先的比例来占用物理资源,我们需要 对客户机能使用的物理资源进行控制。由于每个客户机就是宿主 机Linux系统上的一个普通QEMU进程,所以可以通过控制QEMU进程使用的资源来达到 控制客户机的目的。

1.cgroups简介

cgroups[1](即control groups,控制群组)是Linux内核中的一个特性,用于限制、记 录和隔离进程组(processgroups)对系统物理资源的使用。cgroups最初是由Google的一些 工程师(Paul Menage、Rohit Seth等)在2006年以“进程容器”(process container)的名字 实现的,在2007年被重命名为“控制群组”(Control Groups),然后被合并到Linux内核的 2.6.24版本中。在加入Linux内核的主干之后,cgroups越来越成熟,有很多新功能和控制 器(controller)被加入进去,其功能也越来越强大。cgroups为不同的用户场景提供了一 个统一的接口,这些用户场景包括对单一进程的控制,也包括OpenVZ、LXC(Linux Containers)等操作系统级别的虚拟化技术。一些较新的比较流行的Linux发行版,如 RHEL、Fedora、SLES、Ubuntu等,都提供了对cgroups的支持。

cgroups提供了如下一些功能:

1)资源限制(Resource limiting),让进程组被设置为使用资源数量不能超过某个界 限。如内存子系统可以为进程组设定一个内存使用的上限,一旦进程组使用的内存达到限 额,如果再申请内存就会发生缺乏内存的错误(即:OOM,out of memory)。

2)优先级控制(Prioritization),让不同的进程组有不同的优先级。可以让一些进程 组占用较大的CPU或磁盘I/O吞吐量的百分比,另一些进程组占用较小的百分比。

3)记录(Accounting),衡量每个进程组(包括KVM客户机)实际占用的资源数 量,可以用于对客户机用户进行收费等目的。如使用cpuacct子系统记录某个进程组使用 的CPU时间。

4)隔离(Isolation),对不同的进程组使用不同的命名空间(namespace),不同的 进程组之间不能看到相互的进程、网络连接、文件访问等信息,如使用ns子系统就可以使 不同的进程组使用不同的命名空间。

5)控制(Control),控制进程组的暂停、添加检查点、重启等,如使用freezer子系 统可以将进程组挂起和恢复。

cgroups中有如下几个重要的概念,理解它们是了解cgroups的前提条件。 1)任务(task):在cgroups中,一个任务就是Linux系统上的一个进程或线程。可以 将任务添加到一个或多个控制群组中。

2)控制群组(control group):一个控制群组就是按照某种标准划分的一组任务(进 程)。在cgroups中,资源控制都是以控制群组为基本单位来实现的。一个任务可以被添 加到某个控制群组,也可以从一个控制群组转移到另一个控制群组。一个控制群组中的进 程可以使用以控制群组为单位分配的资源,同时也受到以控制群组为单位而设定的资源限 制。

3)层级体系(hierarchy):简称“层级”,控制群组被组织成有层级关系的一棵控制 群组树。控制群组树上的子节点控制群组是父节点控制群组的孩子,可以继承父节点控制 群组的一些特定属性。每个层级需要被添加到一个或多个子系统中,受到子系统的控制。

4)子系统(subsytem):一个子系统就是一个资源控制器(resource controller),如 blkio子系统就是控制对物理块设备的I/O访问的控制器。子系统必须附加到一个层级上才 能起作用,一个子系统附加到某个层级以后,该子系统会控制这个层级上的所有控制群 组。

目前cgroups中主要有如下10个子系统可供使用。

 ·blkio:这个子系统为块设备(如磁盘、固态硬盘、U盘等)设定读写I/O的访问设置 限制。
·cpu:这个子系统通过使用进程调度器提供了对控制群组中的任务在CPU上执行的控 制。
·cpuacct:这个子系统为控制群组中的任务所实际使用的CPU资源自动生成报告。 
·cpuset:这个子系统为控制群组中的任务分配独立CPU核心(在多核系统)和内存节 点。
·devices:这个子系统可以控制一些设备允许或拒绝来自某个控制群组中的任务的访 问。
·freezer:这个子系统用于挂起或恢复控制群组中的任务。
 ·hugetlb:这个子系统用于控制对大页的使用。 
·memory:这个子系统为控制群组中任务能使用的内存设置限制,并能自动生成那些 任务所使用的内存资源的报告。
 ·net_cls:这个子系统使用类别识别符(classid)标记网络数据包,允许Linux流量控 制程序(traffic controller)识别来自某个控制群组中任务的数据包。
 ·net_prio:这个子系统使得其名下cgroups里面的任务,可以就不同的接口设置从该接 口出去的包的优先级。
·perf_event:这个子系统主要用于对系统中进程运行的性能监控、采样和分析等。 
·pids:这个子系统用于控制cgroups中可以派生(通过fork、clone)出来的子进程、子 线程的数量(pid的数量)。
复制代码

cgroups中层级体系的概念与Linux系统中的进程模型有相似之处。在Linux系统中,所 有进程也是组成树状的形式(可以用“pstree”命令查看),除init以外的所有进程都是一个 公共父进程,即init进程的子进程。init进程是由Linux内核在启动时执行的,它会启动其 他进程(当然普通进程也可以启动自己的子进程)。除init进程外的其他进程从其父进程 那里继承环境变量(如$PATH变量)和其他一些属性(如打开的文件描述符)。

与Linux 进程模型类似,cgroups的层级体系也是树状分层结构的,子节点控制群组继承父节点控 制群组的一些属性。尽管有类似的概念和结构,但它们之间也一些区别。最主要的区别 是,在Linux系统中可以同时存在cgroups的一个或多个相互独立的层级,而且此时Linux系 统中只有一个进程树模型(因为它们有一个相同的父进程init进程)。多个独立的层级的 存在也是有其必然性的,因为每个层级都会给添加到一个或多个子系统下。

原文链接:https://juejin.cn/post/6844904052573077511

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>