实在说来挺故意思,看过去到底是为了看未来,由于历史总是惊人的相似,险些所有的问题都能够在历史长河中寻得答案。可惜的是,但凡历史,最是难写,笔者碍于能力有限,还望大家多指示一二。
作者:范桂飓责编:屠敏来源:"大众号:CSDN(ID:CSDNnews)在打算机科学中,虚拟化技能(Virtualization)是一种资源管理(优化)技能,将打算机的各种物理资源(e.g. CPU、内存以及磁盘空间、网络适配器等 I/O 设备)予以抽象、转换,然后呈现出来的一个可供分割并任意组合为一个或多个(虚拟)打算机的配置环境。

虚拟化技能冲破了打算机内部实体构造间不可切割的障碍,利用户能够以比原来更好的配置办法来运用这些打算机硬件资源。而这些资源的虚拟形式将不受现有架设办法,地域或物理配置所限定。
虚拟化技能是一个广义的术语,根据不同的工具类型可以细分为:
平台虚拟化(Platform Virtualization):针对打算机和操作系统的虚拟化。资源虚拟化(Resource Virtualization):针对特定的系统资源的虚拟化,如内存、存储、网络资源等。运用程序虚拟化(Application Virtualization):包括仿真、仿照、阐明技能等,如 Java 虚拟机(JVM)。这里我们紧张谈论的是平台虚拟化。首先提出第一个问题:当我们谈论平台虚拟化技能,实际在谈论什么?我认为谈论的是 Hypervisor 或称为 VMM(Virtual Machine Monitor),本篇我们紧张回顾 VMM 的发展进程,并思考之中的缘故原由。
二、虚拟化技能发展编年史1. 开篇
1959 年 6 月,牛津大学的打算机教授,克里斯·托弗(Christopher Strachey)在国际信息处理大会(International Conference on Information Processing)上揭橥了一篇名为《大型高速打算机中的韶光共享》(Time Sharing in Large Fast Computer)的学术报告,他在文中首次提出了 “虚拟化” 的基本观点,还论述了什么是虚拟化技能。这篇文章被认为是最早的虚拟化技能论述,从此拉开了虚拟化发展的帷幕。
克里斯·托弗还同时提出了 Multi-Processing(多道程序)这一超前的观点,Multi-Processing 办理了运用程序因等待外部设备而导致处理器空转问题,同时也办理了用户如何调试(Debug)代码的问题。即便在现在看来,多道程序的理念仍是操作系统在 “并发” 领域中的隗宝。
When I wrote the paper in 1959 I, in common with everyone else, had no idea of the difficulties which would arise in writing the software to control either the time-sharing or multi-programming. If I had I should not have been so enthusiastic about them.
——Christopher Strachey
Christopher Strachey
2. 大型机和小型机的虚拟化
1960 年,为了应对物理学领域的打算需求,美国启动 Atlas 超级打算机(Super Computer)项目。同期的英国全国只有 16 台打算机,日不落帝国的谩骂在打算机领域也无法幸免。
1961 年,由麻省理工学院的 Fernando Corbato 教授带领团队开始研发 CTSS(Compatible Time Sharing System,兼容性分时系统)项目,并由 IBM 供应硬件设备和工程师进行支持。分时系统可以说是硬件虚拟化的根本,CTSS 为后来 IBM 的 TSS 打下了根本。
1962 年,第一台 Atlas 超级打算机 Atlas 1 出身,Atlas 1 是第一台实现了虚拟内存(Virtual Memory)观点的打算机,并将其称为一级存储(one-level store)。Atlas 1 还是第一个实现了名为 Supervisor 的底层资源管理组件的打算机,Supervisor 可以通过分外的指令或代码来管理物理主机的硬件资源,例如:中心处理器的韶光分配。
没错,操作系统最早的称谓实在是 Supervisor,今后还被叫过一段韶光的 Master Control Program(主控程序),但终极 Operating System 胜出了。此时你或许能够理解为什么虚拟机管理程序会被统称为 Hypervisor(Super、Hyper 是赞许词,意为超级,但词义上 Hyper 比 Super 还要高等一些)。
1963 年利用打孔机的第一代 Atlas 超级打算机
1960 中期,IBM 在 Thomas J. Watson Research Center (NY) 进行 M44/44X 打算机研究项目。M44/44X 项目基于 IBM 7044(M44)实现了多个具有打破性的虚拟化观点,包括部分硬件共享(partial hardware sharing)、韶光共享(time sharing)、内存分页(memory paging)以及实现了虚拟内存管理的 VMM。
通过这些虚拟化技能,运用程序可以运行在这些虚拟的内存之中,实现了在同一台主机上仿照出多个 7044 系统(44X)。M44/44X 项目首次利用了 VM(Virtual Machine) 和 VMM(Virtual Machine Monitor)一词,被认为是天下上第一个支持虚拟机的系统。
1964 年:IBM 推出了著名的 System/360。你或许有所耳闻,System/360 的开拓过程被视为了打算机发展史上最大的一次豪赌,为了研发 System/360,IBM 决定征召六万多名新员工,创建了五座新工厂。即便如此,当时的出货韶光仍被不断顺延。
吉恩·阿姆达尔是系统主架构师,当时的项目经理佛瑞德·布鲁克斯(Frederick P. Brooks, Jr.)事后根据这项操持的开拓履历,写出了同样著名的《人月神话:软件项目管理之道》(The Mythical Man-Month: Essays on Software Engineering)记述人类工程史上一项里程碑式的大型繁芜软件系统开拓履历。终极,IBM System/360 取得了巨大的商业成功。
System/360 不仅供应了新型的操作系统(让单一操作系统适用于全体系列的产品,这是 System/360 系列大型机成功的关键),还实现了基于全硬件虚拟化(Full Hardware Virtualization)的虚拟机办理方案,包括:页式虚拟内存(4k 分页虚拟存储系统),虚拟磁盘以及 TSS 分时系统。System/360 最多可供应 14 个虚拟机,每个虚拟机具有 256k 固定虚拟内存。
这里有必要着重先容一下 TSS (Time Sharing System,分时共享系统),它能够让一台主机上连接多个带有显示器和键盘的终端,同时许可多个用户通过主机的终端,以交互办法利用打算机,共享主机中的资源。分时操作系统实质是一个多用户交互式操作系统。
个中,“分时” 的含义是将 CPU 占用切分为多个极短(e.g. 1/100sec)的韶光片,每个韶光片都实行着不同的任务。通过对这些韶光片的轮询,就可以将一个 CPU “伪装”(虚拟化)成多个 vCPU,并且让每颗 vCPU 看起来都是并走运行的。终极达到多个用户分享利用同一台打算机,多个程序分时共享硬件和软件资源的效果,TSS 被认为是最原始的虚拟化技能。
可见,最初虚拟化技能的运用和发展源于大型机对分时系统的需求。这种通过硬件的办法来天生多个可以运行独立操作系统软件的虚拟机实例,办理了早期大型打算机只能单任务处理而不能分时多任务处理的问题。
由于这种虚拟化技能是基于硬件设备来实现的,故被称为硬件虚拟化(Hardware virtualization)。但须要把稳的是,这一说法在后来被进一步细分为了狭义的硬件虚拟化技能,现今更加为人多熟知的硬件虚拟化是指:一种对打算机或操作系统的虚拟化,能够对用户隐蔽真实的打算机硬件,表现出另一个抽象的打算平台。
System/360
The Mythical Man-Month: Essays on Software Engineering
3. 伟大源自于伟大!
1974 年,Gerald J. Popek(杰拉尔德·J·波佩克)和 Robert P. Goldberg(罗伯特·P·戈德堡)在互助论文《可虚拟第三代架构的规范化条件》(Formal Requirements for Virtualizable Third Generation Architectures)中提出了一组称为虚拟化准则的充分条件,又称波佩克与戈德堡虚拟化需求(Popek and Goldberg virtualization requirements)即:虚拟化系统构造的三个基本条件。
知足这些条件的掌握程序才可以被称为虚拟机监控器(Virtual Machine Monitor,简称 VMM):
资源掌握(Resource Control)。掌握程序必须能够管理所有的系统资源。等价性(Equivalence)。在掌握程序管理下运行的程序(包括操作系统),除时序和资源可用性之外的行为该当与没有掌握程序时的完备同等,且预先编写的特权指令可以自由地实行。效率性(Efficiency)。绝大多数的客户机指令该当由主机硬件直接实行而无需掌握程序的参与。该论文只管基于简化的假设,但上述条件仍为评判一个打算机体系构造是否能够有效支持虚拟化供应了一个便利方法,也为设计可虚拟化打算机架构给出了辅导原则。同时,Gerald J. Popek 和 Robert P. Goldberg 还在论文中先容了两种 Hypervisor 类型,分别是类型 I 和 类型 II。
类型 II(寄居或托管 Hypervisor):VMM 运行在传统的操作系统上,就像其他打算机程序那样运行。
特点:
VMM 作为运用程序运行在主操作系统环境内;运行效率一样平常较类型 I 低。实现案例:
VMware 5.5 以前版本;Xen 3.0 以前版本;Virtual PC 2004。类型 I(原生或裸机 Hypervisor):这些虚拟机管理程序直接运行在宿主机的硬件上来掌握硬件和管理客户机操作系统。
特点:
须要硬件支持;VMM 作为主操作系统;运行效率高。实现案例:
VMware 5.5 及往后版本;Xen 3.0 及往后版本;Virtual PC 2005;KVM。ps:这里我特意将类型 I 和 II 的顺序调转,至于为什么,从实现案例可以看出类型 I 已然是时期的选择。再一个,诚笃说我确实为这个事实感到震荡,平台虚拟化的雏形竟然在 1974 年就已经确立了的这个事实。
1979 年,Unix 的第 7 个版本引入了 chroot 机制,意味着第一个 操作系统虚拟化(OS-level virtualization) 出身了。chroot 是直到现在我们依然在利用的一个别系调用,这个别系调用会让一个进程把指定的目录作为根目录,它的所有文件系统操作都只能在这个指定目录中进行,实质是一种文件系统层的隔离。
ps:操作系统虚拟化这个说法你或许会感到陌生,但容器(Container)你该当非常熟习了。
在上世纪 60~80 年代,由于虚拟化技能使得大型机和小型机得到了空前的成功。并且在相称长的一段韶光里,虚拟化技能只在大型机和小型机上得到了运用,而在 x86 平台上的运用仍旧进展缓慢。不过也可以理解,以当时 x86 平台的处理能力,搪塞一两个运用程序已然捉襟见肘,还怎么能够将资源分给更多的虚拟运用呢?
而后随着 x86 的盛行,大型机和小型机在新兴的做事器市场中也逐渐失落去了竞争力。
4. x86 架构的虚拟化
直到上世纪 80~90 年代,Intel 公司(戈登·摩尔)提出了摩尔定律,Windows、Mac 等 PC(Personal Computer)电脑被广泛利用,Wintel 同盟势如破竹,还涌现了神一样平常的 Linux 做事器操作系统。
各类缘故原由,到底是 x86 赢得了时期的青睐,成为了做事器的行业标准。或许在那时 Intel 就已经开始思考为何 “生态” 这件事情了。
摩尔定律的传统定义是:半导体芯片上的晶体管密度,均匀每 18-24 个月翻一番。
Wintel 同盟:即微软与英特尔的互助,自 20 世纪 80 年代以来,Wintel 同盟就主导着环球 PC 市场。
GNU/Linux:开源上帝。
随着 x86 做事器和桌面支配的增长也为企业 IT 根本架构带来了新的难题:
根本架构利用率低;根本架构成本高;IT 运维本钱高;故障切换和灾害保护不敷;终极用户桌面的掩护本钱高昂。而办理这些难题便是新时期授予虚拟化技能的历史任务,全体 80~90 年代,虚拟化技能及公司犹如雨后春笋般呈现。
1987 年:Insignia Solutions 公司演示了一个称为 SoftPC 的软件仿照器,这个仿照器许可用户在 Unix Workstations 上运行 DOS 运用。当时一个可以运行 Microsoft DOS 的 PC 须要 1,500 美金,而利用 SoftPC 仿照,就可以直接在大型事情站上运行 Microsoft DOS 了。
1989 年,Insignia Solutions 发布了 Mac 版的 SoftPC,使苹果用户不仅能运行 DOS,还能运行 Windows 操作系统。
1990 年,Keir Fraser 和 Ian Pratt 创建了 XenServer 的初始代码工程(项目)。
1997 年,苹果开拓了 Virtual PC,后来又卖给了 Connectix 公司。
1998 年,著名的 x86 仿真仿照器 Bochs 发布。
1999 年,VMware 公司率先推出针对 x86 平台推出了可以流畅运行的商业虚拟化软件 VMaware Workstation。
2000 年,FreeBSD jail,真正意义上的第一个功能完全的操作系统虚拟化技能。利用这个技能,FreeBSD 的系统管理者,可以创造出几个小型的软件系统,这些软件系统被称为 jails(监狱,即容器。ps:不禁感慨,取名真的很主要)。
2001 年,VMWare 发布 ESX 和 GSX,是 ESXi 的前身。同年,Fabrice Bellard 也发布了目前最盛行的,采取了动态二进制翻译(Binary Translation)技能的开源虚拟化软件 QEMU(Quick EMUlator)的第一个版本。
5. 基于二进制翻译的全虚拟化
此时,虚拟化技能的共同目标便是将 x86 架构转变为通用的共享硬件根本架构,使运用程序运行环境在隔离性、移动性和操作系统类型方面都有选择的空间。首先理解一下 x86 架构的特点。
CPU 为了担保程序代码实行的安全性,多用户的独立性以及担保操作系统的稳定性,提出了 CPU 实行状态的观点。它有效的限定了不同程序之间的数据访问能力,避免了造孽的内存数据操作,同时也避免了运用程序缺点操作打算机的物理设备。
一样平常的,CPU 都会划分为用户态和内核态,而 x86 CPU 更是细分为了 Ring 0~3 四种实行状态。
Ring0 核心态(Kernel Mode):是操作系统内核的实行状态(运行模式),运行在核心态的代码可以无限制的对系统内存、设备驱动程序、网卡接口、显卡接口等外部设备进行访问。
显然,只有操作系统能够无限制的访问内存、磁盘、鼠键等外围硬件设备的数据,由于操作系统便是作为打算机硬件资源管理器而存在的,操作系统便是为了让多个普通运用程序可以更大略、安全的运行在同一台打算机上而存在的 “分外的运用程序”。
Ring3 用户态(User Mode):运行在用户态的程序代码须要受到 CPU 的检讨,用户态程序代码只能访问内存页表项中规定能被用户态程序代码访问的页面虚拟地址(受限的内存访问),而且还只能访问 I/O Permission Bitmap 中规定的能被用户态程序代码访问的端口,不能直接访问外围硬件设备、不能抢占 CPU。
也很显然,所有的运用程序都该当运行在用户态中。当运用程序须要访问外围硬件设备时,CPU 会通过特殊的接口去调用核心态的代码,以这种旁路的办法来运用程序对硬件设备的调用。如果用户态的运用程序直接调用硬件设备的话,就会被操作系统捕捉到并触发非常,弹出警告窗口。
可见,x86 架构与大型机不同,当时的 x86 体系构造缺少必要的针对虚拟化的硬件支持,难以直接知足波佩克与戈德堡的虚拟化需求,以是 x86 架构天然不是一个可虚拟化的架构。
x86 架构的 CPU 中有 17 条指令成为了虚拟化最大的障碍,缺点实行这些指令会导致操作系统显示警告、终止运用程序乃至完备崩溃。当时 VMware 提出理解决这个问题的思路:在虚拟机天生这些分外的指令时将它们 “困住”,然后将它们转换成可虚拟化的安全指令,同时担保其他所有的指令不受到滋扰地实行。这样就产生了一种与主机硬件匹配并保持软件完备兼容性的高性能虚拟机。
这便是 全虚拟化(Full virtualization) 技能出身的背景 —— 必须利用纯软件实现的办法布局 VMM。VMware 创始了这项技能,一举稳坐虚拟化龙头老大。
全虚拟化是指虚拟机仿照了完全的底层硬件,包括处理器、物理内存、时钟、外设等,使得为原始硬件设计的操作系统或其它系统软件完备不做任何修正就可以在虚拟机中运行。客户机操作系统(Guest OS)与真实硬件之间的交互,可以算作是通过一个预先规定的硬件接口进行的。全虚拟化 VMM 以完全仿照硬件的办法供应全部接口(同时还必须仿照特权指令的实行过程)。
全虚拟化的事情事理:虚拟机是对真实打算环境的抽象和仿照,VMM 须要为每个虚拟机分配一套数据构造来管理它们状态,包括 vCPU 的全套寄存器,物理内存的利用情形,虚拟设备的状态等等。
VMM 调度虚拟机时,会将其部分状态规复到 Host OS 中。但并非所有的状态都须要规复,例如主机 CR3 寄存器中存放的是 VMM 设置的页表物理地址,而不是 Guest OS 设置的值。
pCPU 直接运行 Guest OS 的机器指令时,由于 Guest OS 运行在低特权级别(Ring 1),如果 Guest OS 直接访问 Host OS 的特权状态(如写 GDT 寄存器),就会由于权限不敷导致 pCPU 产生非常,然后将运行权主动交还给 VMM。
此外,外部中断的到来也会影响 VMM 的运行。VMM 可能须要先将该虚拟机确当前状态写回到状态数据构造中,剖析虚拟机被挂起的缘故原由,然后代表 Guest OS 实行相应的特权操作。最大略的情形,如 Guest OS 对 CR3 寄存器的修正,只须要更新虚拟机的状态数据构造即可。
一样平常而言,大部分情形下,VMM 须要经由繁芜的流程才能完本钱来大略的操作。末了 VMM 将运行权还给 Guest OS,Guest OS 早年次被中断的地方连续实行,或处理 VMM “塞”入的虚拟中断和非常。
这种经典的虚拟机运行办法被称为 Trap-And-Emulate(捕获-仿照),虚拟机对付 Guest OS 完备透明,Guest OS 不须要任何修正,但是 VMM 的设计会比较繁芜,系统整体性能受到明显的危害。
举例来说:x86 平台中,操作系统实行切换进程页表的操作,真实硬件会通过供应一个特权 CR3 寄存器来实现该接口,操作系统只需实行 mov pgtable, %%cr3 汇编指令即可。而全虚拟化 VMM 就必须要完全地仿照该接口实行的全过程。
如果硬件(紧张是 CPU)不供应虚拟化的分外支持的话,那么这个仿照过程将会十分繁芜:一样平常而言,VMM 必须运行在最高优先级来完备掌握宿主机操作系统(Host OS),而 Guest OS 须要降级运行,从而不能实行特权操作。
当 Guest OS 实行前面的特权汇编指令时,Host OS 产生非常(General Protection Exception),实行掌握权重新从 Guest OS 转到 VMM 手中。VMM 事先分配一个变量作为影子 CR3 寄存器给 Guest OS,将 pgtable(页表)代表的 Guest OS 物理地址(Guest Physical Address)填入影子 CR3 寄存器,然后 VMM 还须要 pgtable 翻译成主机物理地址(Host Physical Address)并填入物理 CR3 寄存器,末了返回到 Guest OS中。随后 VMM 还将处理繁芜的 Guest OS 缺页非常(Page Fault)。
大略来说,便是全虚拟化须要在 VMM 中仿照出一颗包含了掌握单元、运算单元、存储单元、IS(指令集)的 CPU。此外,还须要仿照一张进行虚拟存储地址和物理存储地址转换的页表。此外,还须要在 VMM 仿照磁盘设备掌握器、网络适配器等等各种 I/O 外设接口。
如此依赖,Guest OS 就不知道自己实在是个虚拟机了呀,它收到了欺骗。可以想象得到,全虚拟化这种处理器密集型的虚拟化技能实现是非常困难且低效的。
比较著名的全虚拟化 VMM 有 Microsoft Virtual PC、VMware Workstation、Sun Virtual Box、Parallels Desktop for Mac 和 QEMU。QEMU 在今年(2019)对别传播宣传可以仿照所有设备。天啊,这切实其实是个奇迹般的伟大软件。
但基于这样的条件,全虚拟化 VMM 必须要战胜许多难以办理的问题,例如:
(1)确保 VMM 掌握所有的系统资源
x86 处理器有 4 个特权级别,Ring 0 ~ Ring 3,只有运行在 Ring 0 ~ 2 时,处理器才可以访问特权资源或实行特权指令;运行在 Ring 0 级时,处理器可以访问所有的特权状态。x86 平台上的操作系统一样平常只利用 Ring 0 和 Ring 3 这两个级别,操作系统运行在 Ring 0 级,用户进程运行在 Ring 3 级。
为了知足 资源掌握(Resource Control) 虚拟化需求条件,VMM 就必须运行在 Ring 0 级,同时为了避免 Guest OS 掌握系统资源,Guest OS 不得不降落自身的运行级别,运行在 Ring 1 或 Ring 3 级(Ring 2 不该用)。
(2)特权级压缩(Ring Compression):VMM 利用分页或段限定的办法来保护物理内存的访问,但是 64 位模式下段限定不起浸染,而分页又不区分 Ring 0, 1, 2。
为了统一和简化 VMM的设计,Guest OS 只能和 Guest 进程一样运行在 Ring 3 级。VMM 必须监视 Guest OS 对 GDT、IDT 等特权资源的设置,防止 Guest OS 运行在 Ring 0级,同时又要保护降级后的 Guest OS 不受 Guest 进程的主动攻击或无意毁坏。
(3)特权级别名(Ring Alias):特权级别名是指 Guest OS 在虚拟机中运行的级别并不是它所期望的。VMM 必须担保 Guest OS 不能获知正在虚拟机中运行这一事实,否则可能冲破 等价性(Equivalence) 虚拟化需求条件。
例如:x86 处理器的特权级别存放在 CS 代码段寄存器内,Guest OS 可以利用非特权 push 指令将 CS 寄存器压栈,然后 pop 出来检讨该值。又如:Guest OS 在低特权级别时读取特权寄存器 GDT、LDT、IDT 和 TR,并不发生非常,从而可能创造这些值与自己期望的不一样。
为理解决这个寻衅,VMM 可以利用动态二进制翻译(Binary Translation)的技能,例如预先把 push %%cs 指令更换,在栈上存放一个影子 CS 寄存器值;又如:可以把读取 GDT 寄存器的操作 sgdt dest 改为 movl fake_gdt, dest。
(4)地址空间压缩(Address Space Compression)
地址空间压缩是指 VMM 必须在 Guest OS 的地址空间中保留一部分供其利用。例如:中断描述表寄存器(IDT Register)中存放的是中断描述表的线性地址,如果 Guest OS 运行过程中来了外部中断或触发处理器非常,必须担保运行权立时转移到 VMM 中,因此 VMM 须要将 Guest OS 的一部分线性地址空间映射本钱身的中断描述表的主机物理地址。
VMM 可以完备运行在 Guest OS 的地址空间中,也可以拥有独立的地址空间,后者的话,VMM 只占用 Guest OS 很少的地址空间,用于存放中断描述表和全局描述符表(GDT)等主要的特权状态。无论如何哪种情形,VMM 该当防止 Guest OS 直接读取和修正这部分地址空间。
(5)处理 Guest OS 的缺页非常
内存是一种非常主要的系统资源,VMM 必须全权管理,Guest OS 理解的物理地址只是客户机物理地址(Guest Physical Address),并不是终极的主机物理地址(Host Physical Address)。
当 Guest OS 发生缺页非常时,VMM 须要知道缺页非常的缘故原由,是 Guest 进程试图访问没有权限的地址,或是客户机线性地址(Guest Linear Address)尚未翻译成客户机物理地址,还是客户机物理地址尚未翻译成主机物理地址。
一种可行的办理方法是 VMM 为 Guest OS 的每个进程的页表布局一个影子页表(Shadow Page Table),掩护 Guest Linear Address 到 Host Physical Address 的映射,主机 CR3 寄存器存放这个影子页表的物理内存地址。
VMM 同时掩护一个 Guest OS 全局的 Guest Physical Address 到 Host Physical Address 的映射表。发生缺页非常的地址总是 Guest Linear Address,VMM 先去 Guest OS 中的页表检讨缘故原由,如果页表项已经建立,即对应的 Guest Physical Address 存在,解释尚未建立到 Host Physical Address 的映射,那么 VMM 分配一页物理内存,将影子页表和映射表更新;否则,VMM 返回到 Guest OS,由 Guest OS 自己处理该非常。
(6)处理 Guest OS 中的系统调用(System Call)
系统调用是操作系统供应给用户的做事例程,利用非常频繁。最新的操作系统一样平常利用 SYSENTER/SYSEXIT 指令对来实现快速系统调用。SYSENTER 指令通过 IA32_SYSENTER_CS,IA32_SYSENTER_EIP 和 IA32_SYSENTER_ESP 这 3 个 MSR(Model Specific Register)寄存器直接转到 Ring 0 级;而 SYSEXIT 指令不在 Ring 0 级实行的话将触发非常。
因此,如果 VMM 只能采纳 Trap-And-Emulate 的办法处理这 2 条指令的话,整体性能将会受到极大危害。
(7)转发虚拟的中断和非常
所有的外部中断和 pCPU 的非常直接由 VMM 接管,VMM 布局必需的虚拟中断和非常,然后转发给 Guest OS。VMM 须要仿照硬件和操作系统对中断和非常的完全处理流程,例如 VMM 先要在 Guest OS 当前的内核栈上压入一些信息,然后找到 Guest OS 相应处理例程的地址,并跳转过去。
VMM 必须对不同的 Guest OS 的内部事情流程比较清楚,这增加了 VMM 的实现难度。同时,Guest OS 可能频繁地屏蔽中断和启用中断,这两个操作访问特权寄存器 EFLAGS,必须由 VMM 仿照完成,性能因此会受到危害。Guest OS 重新启用中断时,VMM 须要及时地获知这一情形,并将积累的虚拟中断转发。
(8)Guest OS 频繁访问特权资源:Guest OS 对特权资源的每次访问都会触发 CPU 非常,然后由 VMM 仿照实行,如果访问过于频繁,则系统整体性能将会受到极大危害。比如对中断的屏蔽和启用,cli(Clear Interrupts)指令在 Pentium 4 处理器上须要花费 60 个时钟周期(cycle)。
又比如:处理器本地高等可编程中断处理器(Local APIC)上有一个操作系统可修正的任务优先级寄存器(Task-Priority Register),IO-APIC 将外部中断转发到 TPR 值最低的处理器上(期望该处理器正在实行低优先级的线程),从而优化中断的处理。TPR 是一个特权寄存器,某些操作系统会频繁设置(Linux Kernel 只在初始化阶段为每个处理器的 TPR 设置相同的值)。
显然,基于 Trap-And-Emulate 处理办法的全虚拟化虽能够以纯软件的办法完成虚拟化并办理了许多问题,但同时也带来了极大的设计繁芜性和性能低落。而对付这两个问题,半虚拟化(Partial virtualization) 想到了一个好办法:改造 Guest OS,将 Guest OS 原来所有须要被 VMM 截获、仿照的指令和操作全部改造成与 VMM 协同事情的指令(hypercall)和操作。
VMM 不再遮盖了,由于你(Guest OS)已经知道自己便是个虚拟机了。其核心思想是:动态或静态地改变 Guest OS 对特权状态访问的操作,只管即便减少产生不必要的硬件非常,同时简化 VMM 的设计。
6. 半虚拟化
半虚拟化是一种通过修正 Guest OS 部分访问特权状态的代码以便直接与 VMM 交互的技能。在半虚拟化虚拟机中,部分硬件接口以软件的形式供应给 Guest OS,这可以通过 Hypercall(VMM 供应给 Guest OS 的直接调用,与系统调用类似)的办法来供应。
例如:Guest OS 把切换页表的代码修正为调用 Hypercall 来直接完成修正影子 CR3 寄存器和翻译地址的事情。由于不须要产生额外的非常和仿照部分硬件实行流程,半虚拟化可以大幅度提高性能,比较著名的 VMM 有 Denali、Xen。
2003 年,英国剑桥大学的一位讲师发布了开源虚拟化项目 Xen,并成立 XenSource 公司,通过半虚拟化技能为 x86-64 供应虚拟化支持。同年,Intel 正式公布将在 x86 平台的 CPU 上支持虚拟化技能 VT。同年 VMWare 也被 EMC 收购,成为 EMC 迄今最成功的一笔收购。同年,微软收购 Connectix 公司得到 Virtual PC 虚拟化技能。
相较于全虚拟化,半虚拟化 VMM 只须要仿照部分底层硬件,因此 Guest OS 不做修恰是无法在虚拟机中运行的,乃至运行在虚拟机中的其它程序也须要进行修正,如此代价,换来的便是靠近于物理机的虚拟机性能。
故意思的是,半虚拟化实在也很尴尬,对付 Linux 而言自然是改了就改了,但 Windows 你要怎么改?人家可是闭源的。写到这里,不禁会想起自己写过的代码,拆东墙补西墙可不值得提倡,要从根源上办理问题。而这个根源自然便是 —— CPU。
既然全虚拟化性能低的紧张缘故原由是花费了太多的精力去捕获 CPU 非常并仿照 CPU 行为,那么如果 CPU 本身就为 VMM 供应了便利,那岂不是从根本上办理了这个问题?这便是 硬件赞助虚拟化(Hardware-assisted virtualization) 。
7. 基于硬件赞助的全虚拟化
Intel-VT(Intel Virtualization Technology)和 AMD-V 是目前 x86 平台上可用的两种硬件赞助虚拟化技能。VT-x 为 IA 32 处理器增加了两种操作模式:VMX root operation 和 VMX non-root operation。
VMM 自己运行在 VMX root operation 模式,VMX non-root operation 模式则由 Guest OS 利用。两种操作模式都支持 Ring 0~3 这 4 个特权级,因此 VMM 和 Guest OS 都可以自由选择它们所期望的运行级别,这两种操作模式可以相互转换。
运行在 VMX root operation 模式下的 VMM 通过显式调用 VMLAUNCH 或 VMRESUME 指令切换到 VMX non-root operation 模式,硬件自动加载 Guest OS 的高下文,于是 Guest OS 得到运行,这种转换称为 VM entry。
Guest OS 运行过程中碰着须要 VMM 处理的事宜,例如外部中断或缺页非常,或者主动调用 VMCALL 指令调用 VMM 的做事的时候(与系统调用类似),硬件自动挂起 Guest OS,切换到 VMX root operation 模式,规复 VMM 的运行,这种转换称为 VM exit。
VMX root operation 模式下软件的行为与在没有 VT-x 技能的处理器上的行为基本同等;而 VMX non-root operation 模式则有很大不同,最紧张的差异是此时运行某些指令或碰着某些事宜时,发生 VM exit。
例如:在上面的例子中,Guest OS 能够实行修正页表的汇编指令,再无需 VMM 进行捕获、仿照。从而减少了干系的性能开销,也极大简化了 VMM 设计,进而使 VMM 能够按通用标准进行编写,性能更加强大。
又由于 VMM 和 Guest OS 共享底层的处理器资源,以是硬件须要一个物理内存区域来自动保存或规复彼此实行的高下文。这个区域称为虚拟机掌握块(VMCS),包括客户机状态区(Guest State Area),主机状态区(Host State Area)和实行掌握区。
VM entry 时,硬件自动从客户机状态区加载 Guest OS 的高下文。并不须要保存 VMM 的高下文,缘故原由与中断处理程序类似,由于 VMM 如果开始运行,就不会受到 Guest OS的滋扰,只有 VMM 将事情彻底处理完毕才可能自行切换到 Guest OS。
而 VMM 的下次运行一定是处理一个新的事宜,因此每次 VMM entry 时, VMM 都从一个通用事宜处理函数开始实行;VM exit 时,硬件自动将 Guest OS 的高下文保存在客户机状态区,从主机状态区中加载 VMM 的通用事宜处理函数的地址,VMM 开始实行。而实行掌握区存放的则是可以操控 VM entry 和 exit 的标志位,例如标记哪些事宜可以导致 VM exit,VM entry 时准备自动给 Guest OS “塞” 入哪种中断等等。
客户机状态区和主机状态区都该当包含部分物理寄存器的信息,例如掌握寄存器 CR0,CR3,CR4;ESP 和 EIP(如果处理器支持 64 位扩展,则为 RSP,RIP);CS,SS,DS,ES,FS,GS 等段寄存器及其描述项;TR,GDTR,IDTR 寄存器;IA32_SYSENTER_CS,IA32_SYSENTER_ESP,IA32_SYSENTER_EIP 和 IA32_PERF_GLOBAL_CTRL 等 MSR 寄存器。
客户机状态区并不包括通用寄存器的内容,VMM 自行决定是否在 VM exit 的时候保存它们,从而提高了系统性能。客户机状态区还包括非物理寄存器的内容,比如一个 32 位的 Active State 值表明 Guest OS 实行时处理器所处的生动状态,如果正常实行指令便是处于 Active 状态,如果触发了三重故障(Triple Fault)或其它严重缺点就处于 Shutdown 状态,等等。
实行掌握区用于存放可以操控 VM entry 和 VM exit 的标志位,包括:
External-interrupt exiting:用于设置是否外部中断可以触发 VM exit,而不论 Guest OS 是否屏蔽了中断。Interrupt-window exiting:如果设置,当 Guest OS 解除中断屏蔽时,触发 VM exit。Use TPR shadow:通过 CR8 访问 Task Priority Register(TPR)的时候,利用 VMCS 中的影子 TPR,可以避免触发 VM exit。同时实行掌握区还有一个 TPR 阈值的设置,只有当 Guest OS 设置的 TR 值小于该阈值时,才触发 VM exit。CR masks and shadows:每个掌握寄存器的每一位都有对应的掩码,掌握 Guest OS 是否可以直接写相应的位,或是触发 VM exit。同时 VMCS 中包括影子掌握寄存器,Guest OS 读取掌握寄存器时,硬件将影子掌握寄存器的值返回给 Guest OS。VMCS 还包括一组位图以供应更好的适应性:
Exception bitmap:选择哪些非常可以触发 VM exit。I/O bitmap:对哪些 16 位的 I/O 端口的访问触发 VM exit。MSR bitmaps:与掌握寄存器掩码相似,每个 MSR 寄存器都有一组“读”的位图掩码和一组“写”的位图掩码。每次发生 VM exi t时,硬件自动在 VMCS 中存入丰富的信息,方便 VMM 甄别事宜的种类和缘故原由。VM entry 时,VMM 可以方便地为 Guest OS 注入事宜(中断和非常),由于 VMCS 中存有 Guest OS 的中断描述表(IDT)的地址,因此硬件能够自动地调用 Guest OS 的处理程序。
传统的全虚拟化实现在有了硬件的赞助之后,由于 CPU 引入了新的操作模式,VMM 和 Guest OS 的实行由硬件自动隔离开来,任何关键的事宜都可以将系统掌握权自动转移到 VMM,因此 VMM 能够完备掌握系统的全部资源。Guest OS 也可以运行在它所期望的最高特权级别,因此特权级压缩和特权级别名的问题迎刃而解,而且 Guest OS 中的系统调用也不会触发 VM exit。
硬件利用物理地址访问虚拟机掌握块(VMCS),而 VMCS 保存了 VMM 和 Guest OS 各自的 IDTR 和 CR3 寄存器。因此 VMM 可以拥有独立的地址空间,Guest OS 能够完备掌握自己的地址空间,地址空间压缩的问题也不存在了。中断和非常虚拟化的问题也得到了很好的办理。
VMM 只用大略地设置须要转发的虚拟中断或非常,在 VM entry 时,硬件自动调用 Guest OS 的中断和非常处理程序,大大简化 VMM 的设计。同时,Guest OS 对中断的屏蔽及解除可以不触发 VM exit,从而提高了性能。而且 VMM 还可以设置当 Guest OS 解除中断屏蔽时触发 VM exit,因此能够及时地转发积累的虚拟中断和非常。
其余,纯软件实现的 VMM 目前短缺对 64 位客户操作系统的支持,而 CPU 的虚拟化技能除支持广泛的传统操作系统类型之外,还支持 64 位客户操作系统。硬件赞助虚拟技能提高了虚拟机的性能以及兼容性。
须要把稳的是,上文中我们提到了全虚拟化、半虚拟化和硬件赞助的全虚拟化,但这种分类实际上并不绝对,一个精良的 VMM 每每领悟了多项技能。
例如: VMware Workstation 是一个著名的全虚拟化的 VMM,但是它利用了一种被称为动态二进制翻译(Binary Translation)的技能把对特权状态的访问转换成对影子状态的操作,从而避免了低效的 Trap-And-Emulate 的处理办法,这与半虚拟化相似,只不过半虚拟化是静态地修处死式代码。
看得出硬件赞助虚拟化技能一定是未来的方向,Intel-VT 的处理器级虚拟化技能还须要进行以下优化:
(1)提高操作模式间的转换速率
两种操作模式间的转换发生之如此频繁,如果不能有效减少其转换速率,纵然充分利用硬件特性,虚拟机的整体性能也会大打折扣。早期的支持硬件赞助虚拟化技能的 Pentium 4 处理器须要花费 2409 个时钟周期处理 VM entry,花费 508 个时钟周期处理由缺页非常触发的 VM exit,代价相称高。
随着 Intel 技能的不断完善,在新的 Core 架构上,相应韶光已经减少到 937 和 446 个时钟周期。未来硬件厂商还须要进一步提高模式的转换速率,并供应更多的硬件特性来减少不必要的转换。
(2)优化翻译后援缓冲器(TLB)的性能
每次 VM entry 和 VM exit 发生时,由于须要重新加载 CR3 寄存器,因此 TLB(Translation Lookaside Buffer)被完备清空。虚拟化系统中操作模式的转换发生频率相称高,因此系统的整体性能受到明显危害。一种可行的方案是为 VMM 和每个虚拟机分配一个全局唯一 ID,TLB 的每一项附加该 ID 信息来索引线性地址的翻译。
(3)供应内存管理单元(MMU)虚拟化的硬件支持
纵然利用 Intel-VT 技能,VMM 还是得用老办法来处理 Guest OS 中发生的缺页非常以及Guest OS 的客户机物理地址到主机物理地址的翻译,实质缘故原由是 VMM 完备掌握主机物理内存,因此 Guest OS 中的线性地址的翻译同时牵扯到 VMM 和 Guest OS 的地址空间,而硬件只能看到个中的一个。
Intel 和 AMD 提出了各自的办理方案,分别叫做 EPT(Extended Page Table)和 Nested Paging。这两种技能的基本思想是,无论何时碰着客户机物理地址,硬件自动搜索 VMM 供应的关于该 Guest OS 的一个页表,翻译成主机物理地址,或产生缺页非常来触发 VM exit。
(4)支持高效的 I/O 虚拟化
I/O 虚拟化须要考虑性能、可用性、可扩展性、可靠性和本钱等多种成分。最大略的办法是 VMM 为虚拟机仿照一个常见的 I/O 设备,该设备的功能由 VMM 用软件或复用主机 I/O 设备的方法实现。
例如: Virtual PC 虚拟机供应的是一种比较古老的 S3 Trio64显卡。这种办法提高了兼容性,并充分利用 Guest OS 自带的设备驱动程序,但是虚拟的 I/O 设备功能有限且性能低下。为了提高性能,VMM 可以直接将主机 I/O 设备分配给虚拟机,这会带来两个紧张寻衅:
如果多个虚拟机可以复用同一个设备,VMM 必须担保它们对设备的访问不会相互关扰。如果 Guest OS 利用 DMA 的办法访问 I/O 设备,由于 Guest OS 给出的地址并不是主机物理地址,VMM 必须担保在启动 DMA 操作前将该地址精确转换。Intel 和 AMD 分别提出了各自的办理方案,分别称为 Direct I/O(VT-d)和 IOMMU,希望用硬件的手段办理这些问题,降落 VMM 实现的难度。2004 年,微软发布 Virtual Server 2005 操持,象征着虚拟化技能正式进入主流市场。
2005 年,OpenVZ 发布,这是 Linux 操作系统的容器化技能实现,同时也是 LXC 的核心实现。
2006 年,Intel 和 AMD 等厂商相继将对虚拟化技能的支持加入到 x86 体系构造的中心处理器中(AMD-V,Intel VT-x),使原来纯软件实现的各项功能可以用借助硬件的力量实现提速。同年,红帽将 Xen 作为 RHEL 的默认特性。同年,Amazon Web Services(AWS)开始以 Web 做事的形式向企业供应 IT 根本举动步伐做事,现在常日称为云打算。
ps:虚拟化和云打算不解的渊源自此开始了。
2007 年 1 月,Sun 公司发布了开源虚拟化软件 VirtualBox。同年 Xen 被 Citrix(思杰)收购。
2007 年 2 月,Linux Kernel 2.6.20 合入了由以色列公司 Qumranet 开拓的虚拟化内核模块 KVM(Kernel-based Virtual Machine,基于内核的虚拟机),支持 KVM 的条件是 CPU 必须要支持虚拟化技能。
2008 年第一季度,微软同时发布了 Windows Server 2008 R2 及虚拟化产品 Hyper-V。
2008 年 6 月,Linux Container(LXC) 发布 0.1.0 版本,其可以供应轻量级的虚拟化,用来隔离进程和资源。是 Docker 最初利用的容器技能支撑。
2008 年 9 月 4 日,Red Hat 收购以色列公司 Qumranet,并动手利用 KVM 更换在 Red Hat 中的利用的 Xen。
2009 年 9 月,红帽发布 RHEL 5.4,在原来的 Xen 虚拟化机制之上,将 KVM 添加了进来。同年,阿里云写下第一行代码。
2010年11月,红帽发布 RHEL 6.0,这个版本将默认安装的 Xen 虚拟化机制彻底去除,仅供应 KVM 虚拟化机制。
当年,Xen 虽然作为一项广泛运用于 Linux 发行版中的虚拟化技能,但却迟迟没有集成到 Linux 内核中,红帽大概是出于对这种分开内核的掩护办法感到不爽,加之当时思杰和微软表现的很非常亲密,导致红帽萌生了放弃 Xen 的想法,并在正式采取 KVM 的一年后,就宣告彻底放弃 Xen。硬件赞助虚拟化的到来,Xen 引以为傲的半虚拟化技能也随之在主流 Linux 发行厂商中衰落了。
2010 年 10 月 21 日,NASA 发布了可以 IaaS(根本举动步伐即做事)云操作系统 OpenStack,第一个版本便是众所周知 Austin(奥斯丁)。OpenStack 挽手自主可控的口号,推动了云打算在海内的全面爆发。
2011 年初,IBM 找上老差错红帽,表示 KVM 这个东西值得加大力度去做。于是到了 5 月,IBM 和红帽,联合惠普和英特尔一起,成立了开放虚拟化同盟(Open Virtualization Alliance),加速 KVM 投入市场的速率,由此避免 VMware 一家独大的情形涌现。
同盟成立之时,红帽的发言人表示:“大家都希望除 VMware 之外还有一种开源选择。未来的云根本举动步伐一定会基于开源。我们想要营造一个小厂商们可以轻松加入的生态环境。”
ps:现在转头再看,企业之以是能够长盛不衰,长远的洞察力至关主要。
8. 操作系统虚拟化(容器)
2013 年 3 月 15 日,在加利福尼亚州圣克拉拉召开的 Python 开拓者大会上,DotCloud 的创始人兼首席实行官 Solomon Hvkes 在一场仅五分钟的微型演讲中,首次提出了 Docker 这一观点,并于会后将其源码开源并托管到 Github。
最初的 Docker 便是利用了 LXC 再封装了其他的一些功能。可以看出,Docker 的成功,与其说是技能的创新,还不如说是一次组合式的创新。
2014 年 6 月,Docker 发布了第一个正式版本 v1.0。同年,Redhat 和 AWS 就宣告了为 Docker 供应官方支持。
在传统操作系统中,所有用户的进程实质上是在同一个操作系统的实例中运行,因此内核或运用程序的毛病可能影响到其它进程。操作系统虚拟化(OS-level virtualization) 是一种在做事器操作系统中利用的、没有 VMM 层的轻量级虚拟化技能,内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程(容器),不同实例中的进程完备不理解对方的存在。
操作系统虚拟化看似与上述提到过的几种硬件虚拟化办法一样,都是产生多个操作系统,但操作系统虚拟化与硬件虚拟化之间还是有很多不同之处,个中最核心的差异便是:操作系统虚拟化是操作系统的虚拟化,而硬件虚拟化是打算机的虚拟化。前者隔离操作系统资源,而后者隔离打算机硬件资源。
ps:容器技能之以是火热,是由于容器隔离性封装的特性,为运维能力引入了 “可编程性”,开拓职员借助容器得以 Software Define Operation。
2015 年 7 月 21 日:Kubernetes v1.0 发布!
进入云原生时期。
2018 年,IBM 正式收购 Redhat 以填补在云打算市场的计策失落败。同年,微软收购 Github。开源的历史会铭记这一天。
2019 年,环球最大的开源盛会 KubeCon + CloudNativeCon + Open Source Summit、Open Infrastructure Summit 相继在上海举办。中国的开源会铭记这一天。
注:本篇文章将会一贯更新下去!
四、末了
对付篇幅较长的文章,我都习气利用三句话来进行总结:
虚拟化的发展:纵不雅观虚拟化技能的发展历史,可以看到它始终如一的目标便是实现对 IT 资源的充分利用。虚拟化与云打算:虚拟化是 IT 资源的抽象,云打算则是基于虚拟化实现的更上层的对企业业务能力的抽象。云打算与开源:开源是领导开拓者的苹果,而开拓者则是企业的核心资产。云的天下,得开拓者,得天下。参考文档:https://www.ibm.com/developerworks/cn/linux/l-cn-vt/index.html
作者:范桂飓,九州云(99Cloud)OpenStack 研发工程师,曾先后做事于 Windows Azure、Redhat OpenStack 与 Prophetech HyperMotion。云物互联公号主,现专注于探索云打算、边缘打算、SDN 与物联网的深度结合运用处景。
公众号:CSDN(ID:CSDNnews)
来源:https://mp.weixin.***.com/s/wuQ8-pwqb9qXfOt4w3Zviw
本文由 @CSDN 授权发布于大家都是产品经理,未经作者容许,禁止转载
题图来自Unsplash,基于CC0协议