深入浅谈虚拟化技术

关于这个吧…我先上一个图
千言万语,总之一句话:虚拟化技术是有代价的!会吃掉一小部分资源去跑虚拟化技术

在此篇文章您能了解到:

虚拟化的历史
主流的虚拟化及他们的实现方式
分析这些主流虚拟化的利弊


谈起虚拟化技术,这个定义非常的抽象,但是总的来说是有一个具体的定义

虚拟化是将各种计算机的实体资源,比如尔CPU内存,储存,网络适配器的虚拟化,将一台实体机分成多个虚拟机

要讲到早期的虚拟化技术,就要讲到程序是如何在计算机上执行的。
那先讲讲应用层,我们用的程序系统运行操作系统包含有关于这个程序运行的运行库
如果简单将一个操作系统分成三层,那我们就会得到,第一层是程序层,第二层是主操作系统,第三层就是操作系统的各种资源,比如CPU内存储存网络等
众所周知,操作系统就是一个很大的应用程序,直播说的事情比较低级罢了
我们将程序改为系统,这不就是一个虚拟机的实现嘛?
那么恭喜你,你错了。
如果事情真的这么简单,技术人才就烂大街了
在1974年,两位闲的没事干的计算机科学家发表论文在声明中,明文强调了虚拟化的三个条件
一,等价性虚拟机执行的结果必须要和物理及反馈的结果相同
二,安全性虚拟机互相隔离且与主系统也互相隔离
三,性能 绝大部分指令由CP U去执行,少数指令由虚拟机监视系统(VMM)执行
于逝吧,就出现了两种虚拟化架构,我们暂且称它为I型虚拟化和II型虚拟化吧
图片见上文
哦,差点忘了名字确实就叫I型虚拟化和II型虚拟化
再由上图可以看出,I型可以直接使用硬件,直接勾出多个虚拟化环境
II型依靠主操作系统,利用程序划分出多个隔离空间
举个栗子,VmWare的天选双子,workstation与ESXI
workstation:依靠宿主操作系统,属于II型虚拟化
ESXI:直接是一个操作系统,属于I型虚拟化

那么最早的虚拟机是利用了什么技术呢?

陷阱 & 模拟 技术

什么意思?简单来说就是正常情况下直接把虚拟机中的代码指令放到物理的CPU上去执行,一旦执行到一些敏感指令,就触发异常,控制流程交给虚拟机监视系统,由虚拟机监视系统来进行对应的处理,以此来构建出一个虚拟机环境。

VMWare: 全虚拟· 二进制翻译技术

上述经典的虚拟化方案在Intel x86架构上却遇到了棘手的问题

不同于8086时代16位实地址工作模式,x86架构进入32位时代后,引入了保护模式、虚拟内存等一系列新的技术。同时为了安全性隔离了应用程序代码和操作系统代码,其实现方式依赖于x86处理器的工作状态。

这就是众所周知的x86处理器的Ring0-Ring3四个“环”。

对的没错,就是著名的 X86(32位)架构问题
操作系统内核代码运行在最高权限的Ring0状态,应用程序工作于最外围权限最低的Ring3状态,剩下的Ring1和Ring2主流的操作系统都基本上没有使用。
这里所说的权限,有两个层面的约束:

  • 能访问的内存空间
  • 能执行的特权指令

来关注一下第二点,特权指令。

CPU指令集中有一些特殊的指令,用于进行硬件I/O通信、内存管理、中断管理等等功能,这一些指令只能在Ring0状态下执行,被称为特权指令。这些操作显然是不能让应用程序随便执行的。处于Ring3工作状态的应用程序如果尝试执行这些指令,CPU将自动检测到并抛出异常。
但是这些都是虚拟机必须要用到的东西,所以之前的 陷阱 & 模拟 手段就没法用了

详情

回顾一下前面描绘的理想模式,要这种模式能够实现的前提是执行敏感指令的时候 能够触发异常 ,让VMM有机会介入,去模拟一个虚拟的环境出来。

但现实是,x86架构的CPU指令集中有那么一部分指令,它不是特权指令,Ring3状态下也能够执行,但这些指令对于虚拟机来说却是敏感的,不能让它们直接执行。一旦执行,没法触发异常,VMM也就无法介入,虚拟机就寄寄了!

这结果将导致虚拟机中的代码指令出现无法预知的错误,更严重的是影响到真实物理计算机的运行,虚拟化所谓的安全隔离、等价性也就全是扯淡。

怎么解决这个问题,让x86架构CPU也能支持虚拟化呢?

VMware和QEMU走出了两条不同的路。

VMware创造性的提出了一个二进制翻译技术。虚拟机监视系统在虚拟机操作系统和宿主计算机之间扮演一个桥梁的角色,将虚拟机中的要执行的指令“翻译”成恰当的指令在宿主物理计算机上执行,以此来模拟执行虚拟机中的程序。你可以简单理解成JVM跑JAR,不同的是JVM跑的是预先写好的东西,而虚拟机监视系统模拟执行的就是CPU指令。

另外值得一提的是,为了提高性能,也并非所有的指令都是模拟执行的,VMware在这里做了不少的优化,对一些“安全”的指令,就让它直接执行也未尝不可。所以VMware的二进制翻译技术也融合了部分的直接执行。

对于虚拟机中的操作系统,虚拟机监视系统需要完整模拟底层的硬件设备,包括处理器、内存、时钟、I/O设备、中断等等,换句话说,虚拟机监视系统用纯软件的形式“模拟”出一台计算机供虚拟机中的操作系统使用。

这种完全模拟一台计算机的技术也称为全虚拟化,这样做的好处显而易见,虚拟机中的操作系统感知不到自己是在虚拟机中,代码无需任何改动,直接可以安装。而缺点也是可以想象:完全用软件模拟,转换翻译执行,性能堪忧!

而QEMU则是完全软件层面的“模拟”,乍一看和VMware好像差不多,不过实际本质是完全不同的。VMware是将原始CPU指令序列翻译成经过处理后的CPU指令序列来执行。而QEMU则是完全模拟执行整个CPU指令集,更像是“解释执行”,两者的性能不可同日而语。

Xen:我们自己搞内核!搞半虚拟化!

既然有全虚拟化,那与之相对的也就有半虚拟化,前面说了,由于敏感指令的关系,全虚拟化的VMM需要捕获到这些指令并完整模拟执行这个过程,实现既满足虚拟机操作系统的需要,又不至于影响到物理计算机。

但说来简单,这个模拟过程实际上相当的复杂,涉及到大量底层技术,并且如此模拟费时费力。

而试想一下,如果把操作系统中所有执行敏感指令的地方都改掉,改成一个接口调用(HyperCall),接口的提供方虚拟机监视系统实现对应处理,省去了捕获和模拟硬件流程等一大段工作,性能将获得大幅度提升。

这就是半虚拟化,这项技术的代表就是Xen,一个诞生于2003年的开源项目。

这项技术一个最大的问题是:需要修改操作系统源码,做相应的适配工作。这对于像Linux这样的开源软件还能接受,充其量多了些工作量罢了。但对于Windows这样闭源的商业操作系统,修改它的代码,无异于天方夜谭。

时间之外的往事·硬件支持

硬件辅助虚拟化 VT / AMD-v

折腾来折腾去,全都是因为x86架构的CPU天然不支持经典虚拟化模式,软件厂商不得不想出其他各种办法来在x86上实现虚拟化。

如果进一步讲,CPU本身增加对虚拟化的支持,那又会是一番怎样的情况呢?

在软件厂商使出浑身解数来实现x86平台的虚拟化后的不久,各家处理器厂商也看到了虚拟化技术的广阔市场,纷纷推出了硬件层面上的虚拟化支持,正式助推了虚拟化技术的迅猛发展。

这其中为代表的就是Intel的VT系列技术和AMD的AMD-v系列技术。

硬件辅助虚拟化细节较为复杂,简单来说,新一代CPU在原先的Ring0-Ring3四种工作状态之下,再引入了一个叫工作模式的概念,有 VMX root operation 和 VMX non-root operation 两种模式,每种模式都具有完整的Ring0-Ring3四种工作状态,前者是VMM运行的模式,后者是虚拟机中的OS运行的模式。

VMM运行的层次,有些地方将其称为Ring -1,VMM可以通过CPU提供的编程接口,配置对哪些指令的劫持和捕获,从而实现对虚拟机操作系统的掌控。

换句话说,原先的VMM为了能够掌控虚拟机中代码的执行,不得已采用“中间人”来进行翻译执行,现在新的CPU告诉VMM:不用那么麻烦了,你提前告诉我你对哪些指令哪些事件感兴趣,我在执行这些指令和发生这些事件的时候就通知你,你就可以实现掌控了。完全由硬件层面提供支持,性能自然高了不少。

上面只是硬件辅助虚拟化技术的一个简单理解,实际上还包含更多的要素,提供了更多的便利给VMM,包括内存的虚拟、I/O的虚拟等等,让VMM的设计开发工作大大的简化,VMM不再需要付出昂贵的模拟执行成本,整体虚拟化的性能也有了大幅度的提升。

VMware从5.5版本开始引入对硬件辅助虚拟化的支持,随后在2011年的8.0版本中正式全面支持。于是乎,我们在创建虚拟机的时候,可以选择要使用哪一种虚拟化引擎技术,是用原先的二进制翻译执行,还是基于硬件辅助虚拟化的新型技术。

同一时期的XEN从3.0版本也加入对硬件辅助虚拟化的支持,从此基于XEN的虚拟机中也能够运行Windows系统了。

KVM: 没想到吧,爷来了!

KVM:生来就是给服务器用的

有了硬件辅助虚拟化的加持,虚拟化技术开始呈现井喷之势。VirtualBox、Hyper-V、KVM等技术如雨后春笋般接连面世。这其中在云计算领域声名鹊起的当属开源的KVM技术了。

KVM全称 Kernel-based Virtual Machine ,意为基于内核的虚拟机。

在虚拟化底层技术上,KVM和VMware后续版本一样,都是基于硬件辅助虚拟化实现。不同的是VMware作为独立的第三方软件可以安装在Linux、Windows、MacOS等多种不同的操作系统之上,而KVM作为一项虚拟化技术已经集成到Linux内核之中,可以认为Linux内核本身就是一个HyperVisor,这也是KVM
名字的含义,因此该技术只能在Linux服务器上使用。

KVM技术常常搭配QEMU一起使用,称为KVM-QEMU架构。前面提到,在x86架构CPU的硬件辅助虚拟化技术诞生之前,QEMU就已经采用全套软件模拟的办法来实现虚拟化,只不过这种方案下的执行性能非常低下。

KVM本身基于硬件辅助虚拟化,仅仅实现CPU和内存的虚拟化,但一台计算机不仅仅有CPU和内存,还需要各种各样的I/O设备,不过KVM不负责这些。这个时候,QEMU就和KVM搭上了线,经过改造后的QEMU,负责外部设备的虚拟,KVM负责底层执行引擎和内存的虚拟,两者彼此互补,成为新一代云计算虚拟化方案的天选之子。

新兴的一种虚拟化技术:容器技术

前面谈到的无论是基于翻译和模拟的全虚拟化技术、半虚拟化技术,还是有了CPU硬件加持下的全虚拟化技术,其虚拟化的目标都是一台完整的计算机,拥有底层的物理硬件、操作系统和应用程序执行的完整环境。

为了让虚拟机中的程序实现像在真实物理机器上运行“近似”的效果,背后的HyperVisor做了大量的工作,付出了“沉重”的代价。

虽然HyperVisor做了这么多,但你有没有问过虚拟机中的程序,这是它想要的吗?或许HyperVisor给的太多,而目标程序却说了一句:你其实可以不用这样辛苦。

确实存在这样的情况,虚拟机中的程序说:我只是想要一个单独的执行执行环境,不需要你费那么大劲去虚拟出一个完整的计算机来。

这样做的好处是什么?

虚拟出一台计算机的成本高还是只虚拟出一个隔离的程序运行环境的成本高?答案很明显是前者。一台物理机可能同时虚拟出10台虚拟机就已经开始感到乏力了,但同时虚拟出100个虚拟的执行环境却还是能够从容应对,这对于资源的充分利用可是有巨大的好处。

这个请自行搜索,这里不详细讲述

Hyper-V请见此链接
Hyper-V 技术概述 | Microsoft Learn

3 个赞