【虚拟化】系统虚拟化的主要功能和分类

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介: 【虚拟化】系统虚拟化的主要功能和分类

1.3 系统虚拟化的主要功能和分类

系统虚拟化向下管理硬件资源,向上提供硬件抽象。本节主要介绍系统虚拟化的基本功能(包括CPU、内存和I/O虚拟化),并根据Hypervisor与物理资源和操作系统交互方式的不同,介绍了两种基本的虚拟化分类

然后简要介绍三种虚拟化的实现方式,从而帮助读者在整体上了解虚拟化不同实现方式对功能和性能的影响。

1.3.1 虚拟化基本功能

系统虚拟化架构如图1-4所示(以经典的“一虚多”架构为例),底层是物理硬件资源,包括三大主要硬件:CPU、内存和I/O设备。

Hypervisor运行在硬件资源层上,并为虚拟机提供虚拟的硬件资源。

客户机操作系统(Guest OS)运行在虚拟硬件资源上,这与传统的操作系统功能一致,管理硬件资源并为上层应用提供统一的软件接口。

总览整个架构,Hypervisor应当具有两种功能:

  • ①管理虚拟环境;
  • ②管理物理资源。

(1)虚拟环境的管理:

如上所述,Hypervisor需要为虚拟机提供虚拟的硬件资源,因此至少应当包括三个模块:

  • ①CPU虚拟化模块;
  • ②内存虚拟化模块;
  • ③I/O设备虚拟化模块。

除此之外,既然Hypervisor能够允许多个虚拟机同时执行,那么应当具有一套完备的调度机制来调度各虚拟机执行。

考虑到一个虚拟机可能具有多个vCPU,每个vCPU独立运行,那么Hypervisor调度的基本单位应当是vCPU而非虚拟机。

在云环境下,用户有时需要查询虚拟机的状态或者暂停虚拟机的执行,这也通过Hypervisor实现。

为了便于用户管理自己的虚拟机,云厂商往往会提供一套完整的管理接口(例如Libvirt)支持虚拟机的创建、删除、暂停和迁移等。

(2)物理资源的管理:

除了管理虚拟环境,在某种程度上,Hypervisor还担负着操作系统的职责,即管理底层物理资源、提供安全隔离机制,以及保证某个虚拟机中的恶意代码不会破坏整个系统的稳定性。

此外,一些Hypervisor还提供了调试手段和性能采集分析工具(例如KVM单元测试工具KVM-Unit-Test),便于开发者进行测试与评估,例如可以利用Linux提供的Perf工具查看由各种原因触发的VM-Exit(虚拟机退出)次数。

CPU、内存和I/O设备是现代计算机所必需的三大功能部件。如果系统虚拟化要构建出可运行的虚拟机,CPU虚拟化、内存虚拟化和I/O虚拟化是必要的,它们各自需要实现的功能与解决的问题简要概括如下。

(1)CPU虚拟化。

在物理环境下,操作系统具有最高权限级别,可以直接访问寄存器、内存和I/O设备等关键的物理资源。但是,在虚拟环境下,物理资源由Hypervisor接管,并且Hypervisor处于最高特权级。这也就意味着客户机操作系统处于非最高特权级,无法直接访问物理资源。

因此虚拟机对物理资源的访问应当触发异常,陷入Hypervisor中进行监控和模拟。这些访问物理资源的指令称为敏感指令,上述处理方式称为陷入-模拟(Trap and Emulate)。

在Intel VT-x等硬件辅助虚拟化技术出现之前,软件虚拟化技术只能利用计算机体系中现有的特权级进行处理。这就要求所有的敏感指令都是特权指令,才能让Hypervisor截获所有的敏感指令。

但系统中通常存在一些敏感非特权指令,它们称为“虚拟化漏洞”,CPU虚拟化的关键就是消除虚拟化漏洞。此外,中断和异常的模拟及注入也是CPU虚拟化应当考虑的问题。

虚拟设备产生的中断无法像物理中断一样直接传送到物理CPU上,而需要在虚拟机陷入Hypervisor中时,将虚拟中断注入虚拟机中。虚拟机在恢复执行后发现自己有未处理的中断,从而陷入相应的中断处理程序中。

(2)内存虚拟化。

操作系统对于物理内存的使用基于两个假设:

  • ①内存都是从物理地址0开始的;
  • ②物理内存都是连续的。

对于一台物理机上的多个虚拟机而言,它们共享物理内存资源,因此无法满足假设①。对于假设②,可以采用将物理内存分区的方式保证每个虚拟机看到的内存是连续的,但这样牺牲了内存使用的灵活性。

因此内存虚拟化引入了GPA(Guest Physical Address,客户机物理地址)供虚拟机使用。但是,当虚拟机需要访问内存时,是无法通过GPA找到对应的数据的,需要将GPA转换为HPA(Host Physical Address,宿主机物理地址)。

因此Hypervisor需要提供两个功能:

  • ①维护GPA到HPA的映射关系,即GPA→HPA;
  • ②截获虚拟机对GPA的访问,并根据上述映射关系将GPA转换为HPA。

(3)I/O虚拟化。

在物理环境下,操作系统通过I/O端口访问特定的I/O设备,称为PIO(Port I/O,端口I/O),或者将I/O设备上的寄存器映射到预留的内存地址空间进行读写,称为MMIO(Memory-Mapped I/O,内存映射I/O)。

因此Hypervisor需要截获所有的PIO和MMIO操作并对其进行模拟,再将结果告知虚拟机。设备中断也类似,Hypervisor需要将中断分发到不同的虚拟机中。

此外,当多个虚拟机运行在同一个物理机上时,由于I/O设备只有一份(如网卡)不可能同时供多个虚拟机使用。

Hypervisor需要为每个虚拟机提供一个软件模拟的网卡(也可以采用硬件直通或者硬件辅助虚拟化的方式),这个网卡应当与现实设备具有完全相同的接口,从而允许用户无须修改客户机操作系统中原有的驱动程序就能使用这个虚拟设备。

但软件模拟的方式性能较差,目前一般采用软硬件协同优化的I/O虚拟化提升性能。

1.3.2 虚拟化分类

1974年,Gerald J. Popek和Robert P. Goldberg在虚拟化方面的著名论文Formal Requirements for Virtualizable Third Generation Architectures中提出了一组称为虚拟化准则的充分条件,也称为波佩克与戈德堡虚拟化需求(Popek and Goldberg Virtualization Requirements),即虚拟化系统必须满足以下三个条件。

  • (1)资源控制(Resource Control)。虚拟机对于物理资源的访问都应该在Hypervisor的监控下进行,虚拟机不能越过Hypervisor直接访问物理机资源,否则某些恶意虚拟机可能会侵占物理机资源导致系统崩溃。
  • (2)等价(Equivalence)。在控制程序管理下运行的程序(包括操作系统),除时序和资源可用性之外的行为应该与没有控制程序时完全一致,且预先编写的特权指令可以自由地执行,即物理机与虚拟机的运行环境在本质上应该是相同的。对于上层应用来说,在虚拟机和物理机中运行应该是没有差别的。
  • (3)高效(Efficiency)。绝大多数的客户虚拟机指令应该由主机硬件直接执行,而无须控制程序参与。

该论文为设计可虚拟化计算机架构给出了指导原则,遗憾的是,早期Intel x86架构并不全部符合这三个原则,也就是说,早期x86架构对虚拟化的支持是缺失的,因为其架构包含敏感非特权指令[插图](详见2.1.1节)。Robert P. Goldberg还在其博士论文Architectural Principles for Virtual Computer Systems中介绍了两种Hypervisor类型,分别是Type Ⅰ和Type Ⅱ虚拟化,也就是沿用至今的虚拟化分类方法,如图1-5所示。

根据Hypervisor与物理资源和操作系统交互方式的不同,可以将Hypervisor分为两类。Type Ⅰ Hypervisor直接运行在物理硬件资源上,需要承担系统初始化、物理资源管理等操作系统职能。

从某种程度上来说,Type Ⅰ Hypervisor可以视为一个为虚拟化而优化裁剪过的内核,可以直接在Hypervisor上加载客户机操作系统。它相当于在硬件和客户机操作系统之间添加了一个虚拟化层,避免了宿主机操作系统对Hypervisor的干预。Type Ⅰ Hypervisor包括Xen、ACRN等。

与Type Ⅰ Hypervisor不同,Type Ⅱ Hypervisor运行在宿主机操作系统中,只负责实现虚拟化相关功能,物理资源的管理等则复用宿主机操作系统中的相关代码。

这种类型的Hypervisor更像是对操作系统的一种拓展。KVM就属于Type Ⅱ Hypervisor,它以模块的形式被动态地加载到Linux内核中。Type Ⅱ Hypervisor又名寄宿虚拟机监控系统,它将虚拟化层直接安装到操作系统之上,每台虚拟机就像在宿主机操作系统上运行的一个进程。

一般而言,相对于Type ⅡHypervisor,Type Ⅰ Hypervisor系统效率更高,具有更好的可扩展性、健壮性和性能。然而由于Type Ⅱ Hypervisor使用方便,与宿主机操作系统生态兼容,目前大多数桌面用户使用的都是该类型的虚拟机,目前常见的Type Ⅱ Hypervisor有KVM、VMware Fusion、VirtualBox和Parallels Desktop等。

1.3.3 系统虚拟化实现方式

系统虚拟化技术按照实现方式可以分为基于软件的全虚拟化技术、硬件辅助虚拟化技术和半虚拟化技术。一般来说,虚拟机上的客户机操作系统“认为”自己运行在真实的物理硬件资源上,但为了提升虚拟化性能,会修改客户机操作系统使之与Hypervisor相互协作共同完成某些操作。

这种虚拟化方案称为PV(Para-Virtualization,半虚拟化),与之对应的是全虚拟化(Full Virtualization),无须修改客户机操作系统就可以正常运行虚拟机。下面分别从基于软件的全虚拟化、硬件辅助虚拟化和半虚拟化三个方面对上述虚拟化实现技术进行分析。

1.基于软件的全虚拟化

基于软件的全虚拟化技术采用解释执行、扫描与修补、二进制翻译(Binary Translation,BT)等模拟技术弥补虚拟化漏洞。解释执行采用软件模拟虚拟机中每条指令的执行效果,相当于每条指令都需要“陷入”,这无疑违背了虚拟化的高效原则。

扫描与修补为每条敏感指令在Hypervisor中生成对应的补丁代码,然后扫描虚拟机中的代码段,将所有的敏感指令替换为跳转指令,跳转到Hypervisor中执行对应的补丁代码。

二进制翻译则以基本块为单位进行翻译,翻译是指将基本块中的特权指令与敏感指令转换为一系列非敏感指令,它们具有相同的执行效果。对于某些复杂的指令,无法用普通指令模拟出其执行效果,二进制翻译采用和类似扫描与修补的方案,将其替换为函数调用,跳转到Hypervisor进行深度模拟。

以如下x86指令集中cpuid指令的执行代码为例。cpuid指令是x86架构中用于获取CPU信息的敏感指令。经过二进制翻译后,将其替换为对helper_cpuid的函数调用,即获取虚拟CPU的配置信息并返回,模拟出真实cpuid指令的执行效果。翻译前后代码如下。

对于内存虚拟化,前面提到虚拟化需要引入一层新的地址空间,即GPA。客户虚拟机中的应用使用的是GVA(Guest Virtual Address,客户机虚拟地址),而要访问内存中的数据,必须通过HVA(Host Virtual Address,宿主机虚拟地址)访问HPA。

一种可能的解决方案是,将地址转换分为两部分,分别加载GPT(Guest Page Table,客户机页表)和HPT(Host Page Table,宿主机页表),完成GVA到GPA再到HPA的转换,其中转换GVA→GPA由GPT完成,而转换HVA→HPA由HPT完成,而中间转换GPA→HVA通常由Hypervisor维护,这样通过复杂的GVA→GPA→HVA→HPA多级转换,完成了客户虚拟机的内存访问,开销比较大。

因此基于软件的虚拟化技术引入了SPT(Shadow Page Table,影子页表),记录了从GVA到HPA的直接映射,只需要将SPT基地址加载到页表基地址寄存器(例如CR3)中即可完成从GVA到HPA的转换。由于每个进程有自己的虚拟地址空间,因此SPT的数目与虚拟机中进程数目相同。

为了维护SPT与GPT的一致性,Hypervisor需要截获虚拟机对GPT的修改,并在处理函数中对SPT进行相应的修改。

物理机访问I/O设备一般是通过PIO或MMIO的方式,因此I/O虚拟化需要Hypervisor截获这些操作。在x86场景下,PIO截获十分简单,因为设备发起PIO一般需要执行IN、OUT、INS和OUTS指令,这四条指令都是敏感指令,可以利用CPU虚拟化中提到的方式进行截获。

而对于MMIO而言,CPU是通过访问内存的方式发起的。因此Hypervisor采用一种巧妙的方式解决这一问题:在建立SPT时,Hypervisor不会为虚拟机MMIO所属的物理地址区域建立页表项,这样虚拟机MMIO操作就会触发缺页异常从而陷入Hypervisor中进行处理。

因此,全虚拟化区分普通用户态指令和系统特权指令。前者直接执行即可,而对后者使用陷入和模拟技术返回到虚拟机监视器系统来模拟执行。

问题的关键在于对敏感指令的处理:全虚拟化实现了一个二进制系统翻译模块,该模块负责在二进制代码层面对代码进行转换,从而将敏感代码转换为可以安全执行的代码,避免了敏感指令的副作用。二进制翻译系统往往还带有缓存功能,显著提高了代码转换的性能。

该翻译技术的主要使用者有VMware公司早期版本的系统虚拟化产品。虽然全虚拟化无须对客户机操作系统进行任何修改,但却带来了二进制翻译的开销,导致了性能瓶颈。

2.硬件辅助虚拟化

为了解决软件在虚拟化引入的性能开销,Intel和AMD等CPU制造厂商都在硬件上加入了对虚拟化的支持,称为硬件辅助虚拟化(Hardware Assisted Virtualization)。基于硬件辅助虚拟化,也可以实现全虚拟化,不用修改客户机代码。这里以典型的Intel VT技术为例进行简要说明。

前面提到,原本的x86架构存在虚拟化漏洞,并非所有敏感指令都是特权指令。最直接的解决方案就是让所有敏感指令都能触发异常,但是这将改变指令的语义,导致现有的软件无法正常运行。

于是Intel VT-x引入了VMX(Virtual-Machine Extensions,虚拟机扩展)操作模式,包括根模式(root mode)和非根模式(non-root mode),其中Hypervisor运行在根模式而虚拟机运行在非根模式。

在非根模式下,所有敏感指令都会触发VM-Exit陷入Hypervisor中,而其他指令则可以在CPU上正常运行。VMX的引入使得Hypervisor无须大费周章地去识别所有的敏感指令,极大地提升了虚拟化的性能。

而对于内存虚拟化,前面提到可能需要两次地址转换,这就需要不断地切换页表寄存器CR3的值。因此软件全虚拟化技术引入了SPT,直接将GVA转换为HPA,而Intel VT-x引入了EPT(Extended Page Table,扩展页表)。

原本的CR3装载客户页表将GVA转换为GPA,而EPT负责将GPA转换为HPA,直接在硬件上完成了两次地址转换。

两次地址转换即GVA→GPA→HPA,其中转换GVA→GPA仍由客户机操作系统的GPT转换,不用修改;而第二次GPA→HPA由硬件EPT自动转换,对客户虚拟机透明。

虽然SPT是直接将GVA转换为HPA(GVA→HPA),只有一次硬件转换。在没有页表修改的条件下,SPT更高效;然而客户机页表的修改需要通过VM-Exit陷出到Hypervisor进行模拟以保证页表同步,导致了SPT的性能问题。

采用EPT后,客户机页表的修改不会导致EPT的同步(没有VM-Exit),因此EPT更为高效。此外,前面提到SPT的数量与虚拟机中进程数目相对应,而由于EPT是将GPA转换为HPA,所以理论上只需要为每个虚拟机维护一个页表即可,减少了内存占用。

在I/O虚拟化方面,Intel引入了Intel VT-d(Virtualization Technology for Direct I/O,直接I/O虚拟化技术)等硬件优化技术。相较于软件全虚拟化技术需要对设备进行模拟,Intel VT-d支持直接将某个物理设备直通给某个虚拟机使用,这样虚拟机可以直接通过I/O地址空间操作物理设备。但也引入了新问题,原本物理设备发起直接内存访问需要的是宿主机物理地址,但将它分配给某个虚拟机后,该虚拟机只能为其提供客户机物理地址。

因此Intel VT-d硬件上必须有一个单元(DMA重映射硬件)负责将GPA转换为HPA。这种设备直通分配有一个明显缺陷,即一个物理设备只能供一个虚拟机独占使用,这就需要更多的物理硬件资源。

SR-IOV(Single Root I/O Virtualization,单根I/O虚拟化)设备可以缓解这一问题。每个SR-IOV设备拥有一个PF(Physical Function,物理功能)和多个VF(Virtual Function,虚拟功能),每个VF都可以指定给某个虚拟机使用,这样从单个物理设备上提供了多个虚拟设备分配给不同的虚拟机使用。但SR-IOV的VF数量受硬件限制,限定了虚拟设备的可扩展性。

3.半虚拟化

半虚拟化打破了虚拟机与Hypervisor之间的界限,在某种程度上,虚拟机不再对自己的物理运行环境一无所知,它会与Hypervisor相互配合以期获得更好的性能。在半虚拟化环境中,虚拟机将所有的敏感指令替换为主动发起的超调用(Hypercall)。

Hypercall类似于系统调用,是由客户机操作系统在需要Hypervisor服务时主动发起的。通过Hypercall,客户机操作系统主动配合敏感指令的执行(这些指令受Hypervisor监控),大大减少了虚拟化开销。

相较于全虚拟化的暴力替换,半虚拟化则另辟蹊径。它对客户机操作系统中的敏感指令都进行了替换,取而代之的是Hypervisor新增的Hypercall。这些Hypercall实现了敏感指令本身的功能,同时在每次执行时都确保能够退回到Hypervisor。

此外,不仅仅是敏感指令的处理,如果客户机操作系统能够意识到自身运行于虚拟机环境下,并与Hypervisor进行配合,修改代码进行针对性优化,就能提升性能。

Xen早期采用半虚拟化作为性能提升的主要手段,并大获成功。因此相较于CPU虚拟化,由于I/O半虚拟化性能提升明显,更受开发者的关注,如virtio、Vhost、Vhost-user和vDPA等一系列优化技术被提出来,并且不断演进。因此,相较于全虚拟化,半虚拟化能够提供更好的性能,但代价却是对客户机操作系统代码的修改。

为了支持各种操作系统的各种版本,半虚拟化虚拟机监视器的实现者必须付出大量代价做适配工作(virtio提供了标准化的半虚拟化硬件接口,减少了适配难度),并且由于半虚拟化需要修改源代码,对不开源的系统(如Windows)适配比较困难(目前Windows设备驱动程序也广泛支持virtio接口)

4.虚拟化实现方式小结

表1-1总结了三种虚拟化实现方式对CPU、内存和I/O虚拟化等方面的影响。目前主流硬件架构(包括x86、ARM等)都对硬件辅助虚拟化提供了支持,RISC-V的虚拟化硬件扩展作为重要的架构规范也正在完善中[插图]。

同时,半虚拟化驱动规范virtio接口标准正在普及,目前主流的操作系统都提供了virtio的支持。因此,目前主流的虚拟化实现方式是硬件辅助虚拟化和半虚拟化,大幅降低了虚拟化性能的开销。

在CPU、内存和I/O三类虚拟资源中,前两类都已经得到较好的解决。由于I/O设备抽象困难、切换频繁、非常态事件高发等原因,开销往往高达25%~66%(万兆网卡中断达70万次/秒,虚拟化场景下占用高达5个CPU核),因此I/O成为需要攻克的主要效能瓶颈。

此外,虚拟化可以嵌套(Nested Virtualization),即在虚拟机(L1,第一层)中创建和运行虚拟机(L2,第二层),以此类推(物理机看作第零层,L0)。如果CPU支持嵌套的硬件辅助虚拟化(如Intel x86),则可以降低嵌套的虚拟机性能损失。限于篇幅,本书不深入讨论嵌套虚拟化。

目录
相关文章
|
6月前
|
存储 数据管理 云计算
云计算——存储虚拟化功能
云计算——存储虚拟化功能
176 0
|
虚拟化 Windows
Bios启用Intel VT-x虚拟化功能问题
Bios启用Intel VT-x虚拟化功能问题
150 0
|
16天前
|
存储 Linux 调度
KVM 虚拟化的功能特性
【10月更文挑战第13天】虚拟化技术创建实体资源的虚拟版本,提升资源利用率。KVM(Kernel-based Virtual Machine)作为全虚拟化解决方案,借助Linux内核实现Hypervisor功能,通过模块化方式提供高效的虚拟化环境。
|
1月前
|
机器学习/深度学习 人工智能 5G
探索5G革命中的虚拟化基站(vRAN):定义、功能与前景
探索5G革命中的虚拟化基站(vRAN):定义、功能与前景
86 5
|
2月前
|
5G 网络安全 SDN
网络功能虚拟化(NFV)和软件定义网络(SDN):赋能5G网络灵活、智能演进的关键
网络功能虚拟化(NFV)和软件定义网络(SDN):赋能5G网络灵活、智能演进的关键
63 3
|
6月前
|
Linux Shell KVM
Kali系统基于qemu虚拟化运行img镜像文件
QEMU是一个由Fabrice Bellard创建的开源虚拟化器,能在多种平台上运行,如x86、ARM、PowerPC。它支持硬件仿真和虚拟化,允许在宿主系统上运行不同架构和OS,如Windows、Linux。QEMU特点包括硬件仿真、虚拟化支持(与KVM配合)、磁盘和网络仿真、快照及回滚功能。此外,文档还展示了在Kali Linux中安装和配置QEMU的步骤,包括下载、内存设置、源更新、软件安装、创建桥接脚本以及启动和管理虚拟机。
174 1
Kali系统基于qemu虚拟化运行img镜像文件
|
6月前
|
存储 大数据 虚拟化
【云计算与大数据技术】虚拟化简介及虚拟化的分类讲解(图文解释 超详细)
【云计算与大数据技术】虚拟化简介及虚拟化的分类讲解(图文解释 超详细)
623 0
|
5月前
|
前端开发 安全 Linux
【虚拟化】典型虚拟化系统
【虚拟化】典型虚拟化系统
85 0
|
5月前
|
Linux KVM 虚拟化
系统虚拟化基本概念与发展历史和趋势展望
系统虚拟化基本概念与发展历史和趋势展望
372 0
|
6月前
|
网络安全 SDN 网络虚拟化
《计算机网络简易速速上手小册》第8章:软件定义网络(SDN)与网络功能虚拟化(NFV)(2024 最新版)
《计算机网络简易速速上手小册》第8章:软件定义网络(SDN)与网络功能虚拟化(NFV)(2024 最新版)
136 2