Home 虚拟化技术-概览
Post
Cancel

虚拟化技术-概览

概念

虚拟化技术(Virtualization)是一种资源管理技术,主要通过软件实现,能将计算机的各种实体资源(CPU、内存、磁盘空间、网络等)进行抽象和分割, 并创建出一个或多个虚拟的计算机环境。一台物理计算机通过虚拟化技术,可以实现同时运行多个独立的操作系统(虚拟的)或应用程序。 该技术可以提高计算机资源利用率,降低硬件成本,简化管理和维护工作等。虚拟化技术广泛应用于服务器、云计算、开发和测试等领域。

几个关键术语

  • Guest VM(客户机): 在虚拟化环境中运行的虚拟计算机操作系统实例,也称为虚拟机客户机。
  • Hypervisor(虚拟化管理程序): 也称为虚拟机监视器(VMM),是管理宿主机和虚拟机客户机之间资源分配和交互的软件层。
  • Host(宿主机): 运行虚拟化软件的物理计算机。 宿主机通过虚拟化软件创建和管理多个虚拟机客户机。

在一台物理机(Host)上,通过一些虚拟化管理程序(Hypervisor),也叫虚拟机监视器(Virtual Machine Monitor,VMM), 可以模拟出多台虚拟机(Virtual Machine,简称VM),每个虚拟机中一般会运行一个操作系统,把这种虚拟化环境中运行的操作系统示例叫 Guest VM(客户机)

虚拟化-技术实现分类

根据虚拟机监视器(VMM,Virtual Machine Monitor)支持的虚拟机制的不同,guset VM的运行模式主要分为 完全虚拟化(Full Virtualization)类虚拟化(Para Virtualization)

虚拟化技术参考图
虚拟化技术图示

全虚拟化 Full Virtualization

全虚拟化(Full Virtualization ,完全虚拟化)中,客户机操作系统完全不知道它正在运行在虚拟化环境中,而是认为它直接运行在硬件上。 在这种情况下,要求虚拟机监视器(VMM)负责虚拟化所有硬件资源,并正确处理guest所有可能的指令。包括硬件资源的划分,CPU指令的翻译执行等。

根据这种特性可以看出,全虚拟化对guest OS兼容性更好,guest OS无序任何改动,guest OS就像在物理机中运行一样。缺点是运行性能较差。

类虚拟化 Para Virtualization

类虚拟化(Para Virtualization,半虚拟化),也是利用Hypervisor来实现对底层硬件的共享访问,但是需要guest OS适当修改自身源代码, 以适配半虚拟化技术,性能强,兼容性不好(一定需要修改原本OS的代码,除非原本OS已经适配好了)。

因为在在不同类型的CPU中,有些指定是较难以虚拟化的,尤其是CISC架构的CPU。如果要实现全虚拟化,就需要通过二进制代码翻译(binary translation) 等手段,扫描并捕获guest的二进制代码,将难以虚拟化的指令转换成支持虚拟化的指令运行(ABI级别)。正是针对这个原因,半虚拟化就是要求guest OS直接修改 自身操作系统的内核代码,将那些难以虚拟化的指令改掉,改为方便虚拟化的指令来代替,这样就能能很好的与VMM配合工作,达到与物理机相近的性能。

像是一些guest OS中使用的特权指令,CPU运行等级切换等。就是一个比较边界的指令,会破坏guest OS和物理机OS的隔离等,就需要VMM来动态地“修改”这些指令, 修改方式,如vmware有一个二进制翻译机制,qemu使用纯软件模拟,另外还有一些硬件辅助虚拟化指令可以帮助。

硬件辅助虚拟化技术 Hardware-Assisted Virtualization

以前的x86 CPU并没有虚拟化模式,由于VMM软件要完成一个虚拟化指令的翻译等工作,性能表现不是很好。CPU厂商又看到了虚拟化支持的市场需求,就在CPU硬件层面 添加一些虚拟化支持。让硬件参与进来,大大提高性能。除了CPU,还有内存,IO,网络等,也不断发展硬件层面的支持。

硬件辅助虚拟化技术是一种通过硬件支持来提高虚拟化性能和安全性的技术。

传统的虚拟化技术需要使用软件模拟CPU、内存、磁盘等硬件资源,这会导致性能下降和安全风险。而硬件辅助虚拟化技术则是 通过在CPU和其他硬件组件中添加虚拟化相关的功能,来优化虚拟化的性能和安全性

常见的硬件辅助虚拟化技术包括虚拟化扩展指令集、I/O虚拟化支持、内存管理单元(MMU)虚拟化支持等

  • Intel VT和AMD-V:这两种技术都是基于CPU的硬件支持,可以通过扩展指令集和特殊处理器模式来提高虚拟化性能和安全性。
  • I/O虚拟化:I/O虚拟化技术可以将虚拟机直接连接到物理网络或存储设备,从而避免了数据在虚拟机和主机之间的拷贝,提高了数据传输速度和效率。
  • SR-IOV:SR-IOV是一种通过PCI Express总线进行I/O虚拟化的技术,可以将物理设备虚拟化为多个逻辑设备,并将它们直接分配给虚拟机,从而提高了I/O性能。

这些技术的使用可以帮助虚拟机监控程序(VMM)显著提高虚拟化的性能和安全性,但是需要硬件平台支持。

容器技术 LXC Docker

容器技术(docker)不是传统的虚拟化技术,是对应用程序的运行环境的一个包装,只提供一个应用程序的运行时环境,是在操作系统层面之上的。 传统的虚拟化是针对整个硬件环境虚拟化的,通过虚拟的硬件环境来实现运行一个guest OS。容器技术则是针对应用程序运行环境虚拟化的,通过虚拟化的 操作系统运行时环境,来运行单个程序,实现应用程序的虚拟化。

因为很多应用程序并不需要达到像在物理机上运行的效果,HyperVisor所实现的一套虚拟客户机对于应用程序来说可能是多余的,而且资源开销极大,“没必要”。

容器技术主要优点是轻量,资源开销很小,效率高。通过软件层面上的逻辑隔离实现出一个个程序运行的空间。容器内的程序和真实系统中运行的程序跑在同一个操作系统内核 和硬件CPU上,所以不需要CPU指令的虚拟化翻译,效率也会很高。同样,缺点也是因为这个,软件实现出来的隔离肯定不如硬件实现出来的安全。由于是用同一个操作系统内核, 如果内核存在漏洞被利用,容器内的程序有可能实现突破容器限制,影响或破坏宿主计算机系统的。

容器技术参考图
容器技术图示

超轻量虚拟化

传统虚拟化技术,硬件层隔离比较好,但是资源占用大。容器技术则相反,隔离性没那么安全,但资源占用极小。于是现在又慢慢提出了 超轻量虚拟化 的方案。 将二者结合并定制化。

亚马逊推出的 firecracker 就是一个典型的代表。将虚拟化技术的强隔离性和容器技术的轻量性进行融合,提出了一个microVM的概念,底层通过KVM虚拟化技术 实现各个microVM的强隔离,而隔离的虚拟机中运行的是一个个精简版的微型操作系统,砍掉了大量无用的功能,专为容器设计的微型OS。 超轻虚拟化如今成为一个新的浪潮,除了AWS的firecracker,谷歌的gVisor, Intel主导的NEMU也在向这个领域开始发力。

典型的虚拟化产品和容器产品

虚拟化典型产品:

  • VMware 相关套件(ESXi等),VMware创造性的提出了一个二进制翻译技术。VMM在虚拟机操作系统和宿主计算机之间扮演一个桥梁的角色, 将虚拟机中的要执行的指令“翻译”成恰当的指令在宿主物理计算机上执行。

  • QEMU,兼容性好,完全软件层面的“模拟”执行整个CPU指令集,更像是“解释执行”,性能远不及VMware的机制,性能较差。目前qemu已支持使用kvm加速CPU性能,

  • Hyper-V,这是微软的一款虚拟化产品,适合虚拟化运行windos系统。它是微软第一个采用类似Vmware ESXi和Citrix Xen的基于hypervisor的技术。 是微软提出的一种系统管理程序虚拟化技术,能够实现桌面虚拟化.从Windows Server 2008之后,微软的服务器系统版本 可以在服务器管理器上进行安装。

  • KVM,全称为kernel-based Virtual Machine,是一个开源的系统虚拟化模块,基于linux内核的原生虚拟机。它支持硬件虚拟化扩展(x86架构 Intel VT 或 AMD-V)。 由于它是集成在linux内核中的,相当于将Linux内核本身就作为一个Hypervisor,不像其他软件需要安装。

  • Xen Server,半虚拟化,性能特别好,兼容性差 需要使用专门修改之后的内核,修改操作系统源码,做相应的适配工作。由于linux是开源的,适配还好。

  • 其他软件,如virtual box,Window-WSL等。

  • libvirt库(额外补充)。它是一种用于管理不同虚拟化平台(如KVM、Xen、QEMU等)的开源虚拟化API库,提供了一组统一的API,还有守护daemon程序,命令行工具, 让开发人员能够以统一的方式管理不同的虚拟化平台,进行统一的应用编程管理,包括创建、启动、停止、暂停和恢复虚拟机等,还提供了存储和网络的支持。 该库至此C,Python,Java,Go等API接口,并有一个对应的命令行工具。

容器产品:

  • LXC(LinuX Container),作系统层面的虚拟化,通过Linux内核的Cgroups技术和namespace技术的支撑,隔离操作系统文件、网络等资源, 在原生操作系统上隔离出一个单独的空间,将应用程序置于其中运行,这个空间的形态上类似于一个容器将应用程序包含在其中,故取名容器技术。

  • Docker,很火,Docker技术底层原理与LXC没有本质区别,Docker在LXC的基础上更进一步,将执行执行环境中的各个组件和依赖打包封装成独立的对象,更便于移植和部署。

硬件虚拟化分类

具体硬件的虚拟化上,有CPU虚拟化,内存虚拟化,IO虚拟化,网络虚拟化等。

CPU虚拟化

大致实现过程:物理CPU(pCPU)经过VMM抽象为多个虚拟CPU(vCPU),guest OS视角中都是pCPU,实际vCPU分时复用pCPU。 硬件细节上更复杂,硬件CPU为了更好的提供对vCPU的调度和切换,有硬件辅助功能,Intel推出了VT-x(Virtualization Technology for x86)的CPU虚拟化扩展技术, AMD也推出了被称为AMD-V的对应技术。都需要在BIOS中打开(执行特定CPU指令开启)。

内存虚拟化

现代OS对内存的管理一般使用MMU,OS中使用虚拟内存。而虚拟机要使用内存时,需要对HOST中虚拟内存进一步虚拟化。 在现代OS中,CPU访问的都是虚拟地址,虚拟地址经过MMU单元,最终转换成实际的物理内存地址。但是在Guest OS中,Guest OS经过转换得来“物理地址”,在Host OS中其实 仍然是一个Host OS中的虚拟地址,还需要再转换一次。即出现了一个中间态的 Guest Phyical Address,除非Guest OS不用MMU,直接用实地址,一般来说也少见。 而内存虚拟化,一个主要功能就解决这个二次地址装换的问题。

软件实现 - 影子页表技术
为了支持GVA->GPA->HPA的两次转换,可以计算出GVA->HPA的映射关系,将其写入一个单独的影子页表(sPT - shadow Page Table)。在一个运行Linux的guest VM中, 每个进程有一个由内核维护的页表,用于GVA->GPA的转换,这里我们把它称作gPT(guest Page Table)。VMM层的软件会将gPT本身使用的物理页面设为write protected的, 那么每当gPT有变动的时候(比如添加或删除了一个页表项),就会产生被VMM截获的page fault异常,之后VMM需要重新计算GVA->HPA的映射,更改sPT中对应的页表项。

硬件辅助 - EPT/NPT
纯软件实现时,内存开销增加,且对CPU也有一些额外的任务。CPU厂商推出了硬件辅助的内存虚拟化技术, 比如Intel的EPT(Extended Page Table)和AMD的NPT(Nested Page Table),它们都能够从硬件上同时支持GVA->GPA和GPA->HPA的地址转换的技术。 EPT/NPT就是一种扩展的MMU,它可以交叉地查找gPT和nPT两个页表。GVA->GPA的转换依然是通过查找gPT页表完成的,而GPA->HPA的转换则通过查找nPT页表来实现, 每个guest VM有一个由VMM维护的nPT。

IO虚拟化

IO虚拟化情况比较复杂,因为IO设备只有一套,不一定能复用。主要分两类机制,一类是最终传入真实硬件的passthrough,另一类是不一定需要写入真实硬件的emulation。

Passthrough

IO直通,也叫IO透传(更多特指网卡设备相关),让guest OS能直接访问物理设备。对于使用MMIO统一编址的,访问设备内存近似于访问普通内存,在内存虚拟化中已可以实现。 主要有的一个问题是DMA,IO设备大量使用DMA技术,而DMA是需要设备实际的物理地址的,在Guest OS中,错把GusetPA当成HostPA,那么DMA控制器肯定是不能正常工作的, 因为地址不对。

针对该问题,硬件上也提供了解决办法。搞了一个硬件,原理类似内存虚拟化的EPT/NPT技术,不过是专门来转换IO设备地址的,通过查找专门给IO用的 IO page table实现。 在x86架构上,就如Intel的VT-d(Virtualization Technology for Direct I/O),在ARM架构上,也有类似的东西,叫 SMMU(System MMU)

虽然可以访问到IO设备了,性能也较好,但仍有一个问题,就是根本的,硬件设备本身可能设计的很简单,没有支持类似于多个client来共用它的功能,而且,当有多个Guest OS 要共用同一个设备时,会出现并发访问的情况,尤其在进行设备初始化时,多半会有问题,所以该方式主要适用于将设备分配给一个虚拟机OS。

为了解决该问题,x86上PCI-SIG发布了一个SR-IOV (Single Root I/O Virtualizmion) 规范,其中详细阐述了硬件供应商在多个虚拟机中如何共享单个 I/O 设备硬件。 SR-IOV标准定义了设备原生共享所需的「软硬件支持」。硬件支持包括芯片组对 SR-IOV 设备的识别,为保证对设备的安全、隔离访问还需要北桥芯片的 VT-d 支持, 为保证虚拟机有独立的内存空间,CPU 要支持 IOMMU。软件方面,VMM 将驱动管理权限交给 Guest,Guest 操作系统必须支持 SR-IOV 功能。

简单来说,硬件和软件需要同时支持SRIOV,才能使用该技术,该技术在PCI设备虚拟化中较常见。它允许单个物理设备(如网卡)被划分为多个虚拟设备(VF), 每个VF都可以被直接分配给不同的虚拟机(VM),提高系统虚拟化的性能和可扩展性。在SR-IOV中,物理设备通过一个物理功能(PF)与主机操作系统通信, 并负责管理整个设备、完成DMA操作,控制VF的资源等。VF是由PF创建的虚拟设备,在虚拟机中类似于物理设备,有自己的MAC地址和PCIe地址,但是它们只能由PF配置和控制。 VF可以直接分配给虚拟机,这使得虚拟机能够直接与网络设备通信,避免了数据包的复制和处理,降低了虚拟化带来的性能损失。

在主机操作系统中,PF通过驱动程序来配置和管理VF,驱动程序需要支持SR-IOV扩展。在虚拟机中,VF以类似于物理设备的方式出现,在虚拟化环境中提供I/O功能。 PF可以管理设备的全局资源,VF只能使用设备的部分资源,还是由PF分配过来的,主要是功能层面的。PF使用的驱动会比VF使用的驱动更复杂,如要操作硬件,DMA,管理VF等。

Emulation

IO emulation,IO模拟,模拟虚拟机中“有”这么个设备,主要是对驱动程序而言,可以直接使用,就和物理机一样,是无感的。

Guest OS中访问该设备时,对设备的访问可以被VMM捕获(如果是io独立编址的可以捕获io命令,如果是mmio的可以捕获page fault),然后,这个模拟的设备就看VMM如何 实现返回IO请求了。这里面也主要分两种情况,IO全虚拟化和IO半虚拟化

IO全虚拟化,通过软件模拟硬件,在虚拟机中模拟出和物理设备完全一致的设备(中断,DMA和其他硬件资源),行为完全一致,guest OS访问该设备时,被VMM捕获,VMM内部 通过软件去模拟硬件,主要特点:对guest os中的驱动程序友好,兼容性最佳,驱动无须修改,就和物理机中是一样的,但缺点就是性能较差,典型的有QEMU模拟器。

IO半虚拟化,则是和主机共享设备了,guest os中的驱动知道自己是在虚拟机中,驱动程序和物理机中的不同,需要适当修改,以实现和主机的设备共享。特点是性能提升明显,但是 缺点就是兼容性不好,要求guest os中的驱动进行修改适配。主要实现原理:(1)采用 I/O 环机制,使Guest OS和Host OS之间可以共享内存,减少了虚拟机与VMM 之间的交互; (2)添加了一个事件通知和回调机制,实现 Guest OS与 VMM 之间的通信。Guest OS需要使用该机制替代原本的硬件中断机制,可以减少上下文切换开销,提高性能,但是,也就 要求驱动程序修改原有代码了。

这种IO半虚拟化机制也叫前端后端架构(Split IO)。前端/后端架构也称为“Split I/O”,即将传统的I/O驱动模型分为两个部分,一部分是位于客户机OS内部的设备驱动程序 (前端),该驱动程序不会直接访问设备,所有的I/O设备请求会转发给位于一个特权虚机的驱动程序(后端),后端驱动可以直接调用物理I/O设备驱动访问硬件。前端驱动负责接收 来自其他模块的I/O操作请求,并通过虚拟机之间的事件通道机制将I/O请求转发给后端驱动。后端在处理完请求后会异步地通知前端。相比于全虚模型中VMM需要截获每个I/O请求并 多次上下文切换的式,这种基于请求/事务的方式能够在很大程度上减少上下文切换的频率,并降低开销。但是这种I/O模型有一个很大的缺点,要修改操作系统内核以及驱动程序, 因此会存在移植性和适用性方面的问题,导致其使用受限。

使用这种技术的一个典型就是 virtio 技术。该技术已经被主流的操作系统接纳编入内核,因此virtio也已经成为半虚拟化的一套事实标准。 virtio是一种用于IO虚拟化的技术,它提供了一组标准接口和协议,使得虚拟机能够与底层物理设备进行高效的通信。virtio技术采用了一些优化措施, 如使用轮询模式代替中断模式来减少上下文切换,以及使用共享内存等技术减少复制数据的次数,从而提高了虚拟机IO性能。一些主要特点:

  • 虚拟设备模型:virtio 定义了一种通用的虚拟设备模型,包括块设备、网络设备、串口等类型。这些虚拟设备与物理设备的接口类似,但是由虚拟机监控程序 (VMM) 管理。
  • 面向共享内存的 I/O:为了避免不必要的上下文切换和数据复制,virtio 使用共享内存来传输数据。虚拟机和主机之间的共享内存通过 DMA(直接内存访问)方式进行读写操作。
  • 零复制技术:为了进一步提高性能,virtio 使用零复制技术来避免数据的多次复制。通过在共享内存中使用链表描述符,可以将数据包从虚拟机中直接传输到网络驱动程序,而不需要复制到 VMM 中。
  • 自适应特性:virtio 设备支持自适应特性,可以根据虚拟机的需求进行灵活的配置。例如,网络设备可以支持软件中断或硬件中断,以满足不同虚拟机的网络负载需求。

正如上面所提及的,这种半虚拟化需要对guest os中的驱动进行“改造”才能使用。 virtio相关文档及API:
https://docs.oasis-open.org/virtio/virtio/v1.1/
https://libvirt.org/formatdomain.html#elementsDevicesGuest

可参考书籍

This post is licensed under CC BY 4.0 by the author.