虚拟化的层次与机制

最近几年随着并行计算、集群等技术的火热,虚拟机领域焕发了第二春。虚拟化就是指多台虚拟机共享一台物理机硬件的计算机体系结构技术。虚拟化的基本思想是分割软硬件以产生更好的系统性能(实际上,软硬件资源并没有增加,只是利用率提高了)。一个例子就是常见的“虚拟内存”,通过将一部分不用的磁盘写为页面文件,可以获得更大的内存地址空间,我们就可以跑更大的程序了。

1.  层次

我们都知道,传统方式是应用程序跑在操作系统上,而操作系统需要适应主机的特定体系结构,比如x86的机器上就只能跑win,linux,MaxOS等几种,AIX就没法跑了。

有了虚拟化之后,用于的应用程序由相应的客户操作系统管理,且1-n个客户操作系统可以独立于主机的操作系统,运行在同一个硬件上,且不需要适配硬件的特定体系结构。这通常通过增加一个虚拟化层来实现,该虚拟化层称为hypervisor或VMM(Virtual Machine Monitor)。

虚拟化层将主机的物理硬件资源虚拟为可被各虚拟机互斥使用的虚拟硬件资源,这可以在不同的层面实现,如下图:

层次 例子
应用程序级 JVM/.Net CLR
库支持(用户级API)级 WINE
操作系统级 Docker
硬件抽象级 VMware/Xen/KVM
指令集体系结构级 Bochs

我们从下往上看。

指令集体系结构级:

也称为ISA(Instruction Set Architecture)级,通过使用物理主机的ISA模拟一个给定的ISA来实现。基本的模拟方式是“代码解释”,一个软件翻译层的程序将源指令逐条翻译为目标指令,一条源指令可能会对应上百条目标指令来实现相同的功能。为改进性能,出现了动态二进制翻译技术,将动态源指令的基本块转换为目标指令,基本块可以转化为超级块来进一步提升转换的效率。尽管如此,这种方式还是五种层次中效率最低的。

一个典型的代表是Bochs,可以在各种Unix like系统中模拟x86平台,包括指令集、I/O、内存、BIOS等都可以模拟。一些爱折腾的大仙在Android上装windows就是用了这种方式(一个例子见 http://bbs.hiapk.com/thread-4750312-1-1.html
),当然速度惨不忍睹就是了。

硬件抽象级:

该类虚拟化直接在原始硬件上进行。该方法虚拟CPU、内存和I/O设备,目的是通过多个并行用户来改进硬件资源的利用率。该类的典型代表是常用的VMware和Xen。这个层级的虚拟化有全虚拟化、半虚拟化等方式,参见第2部分介绍。

硬件级别的第一个问题是CPU虚拟化。如果当VMM/hypervisor运行在管理模式时,CPU支持在用户模式运行虚拟机的特权指令和非特权指令,则该CPU体系结构是可虚拟化的。RISC的所有控制敏感指令和行为敏感指令都是特权指令,因此RISC CPU是天然可虚拟化的(指这些指令都会自动陷入hypervisor)。而x86体系结构并不是为虚拟化设计,如果套用全虚拟化、半虚拟化等方式,则效率较低。为此提出了一种“硬件辅助的CPU虚拟化”特殊处理,引入一种特殊的运行模式和指令,使得VMM和操作系统可以运行在不同模式中。在Intel和AMD的x86处理器中,这种模式称为特权模式(位于环1),于是操作系统仍运行在环0(x86中操作系统只能跑在环0,见http://baike.baidu.com/link?url=sxY1XeWXddheQHsPnAOLIUpnHF6VWLCrw1IYv67T3BPaLAcnb5-j0NQpdY_B0D8iIFmUIh6OnENGyBAjsEgR1q),hypervisor运行在环1,所有特权指令和敏感指令都会自动陷入到hypervisor中。

通常来讲硬件辅助虚拟化应具有更高的效率,然而,由于从hypervisor到客户操作系统需要在处理器模式之间切换(用户模式和特权模式),会引起较高的开销,有时并不会优于二进制翻译。因此,如VMware等现在使用混合的方法,一部分任务交给硬件,其余则仍由软件处理。

内存虚拟化则类似于现代操作系统的虚拟内存。不同的是虚拟内存只有一级映射,而内存的虚拟化需要客户操作系统和VMM分别维护“虚拟内存——物理内存”和“物理内存——机器内存”的映射,共两级映射。VMware使用影子页表进行虚拟内存到机器内存的地址转换。但该技术效率太低(是早期VMware巨慢的原因之一),Intel开发了基于硬件的EPT(扩展页表)技术来加以改进,下图为该技术的示意图(盗的台巴子的,原文找不到了)。(AMD也有类似的技术称为NPT)

I/O虚拟化包括管理虚拟设备和共享的物理硬件之间I/O请求的路由选择。有如下三种方式:全设备模拟、半虚拟化和直接I/O,我也不是很懂就不展开讲了。只知道VMware用的是全设备模拟。

该类虚拟化由于可以得到CPU级别的支持,性能是比较高的,但是VMM仍然需要自己实现调度器、内存管理器等部件,因此不论VMware还是Xen的代码都比较庞大。

操作系统级:

指处于传统操作系统和用户应用程序之间的抽象层。操作系统级虚拟化在一个单一的物理服务器上创建隔离的容器和操作系统实例,常被用来创建虚拟主机环境,在大量互斥的不信任用户之间分配硬件资源。这种虚拟机也称为VE(虚拟执行环境)、VPS(虚拟专用系统)或容器。VE有自己的进程、文件系统、用户账号、IP地址、路由表、防火墙规则及其他设置。尽管VE可为不同用户分别定制,但它们仍共享同一个操作系统。

操作系统级虚拟化方案解决了硬件级虚拟化的很多问题:首先物理机器和虚拟机实例数可以动态改变;其次硬件级虚拟化的虚拟机初始化很慢,而操作系统级虚拟化几乎不需要时间;第三就是硬件全虚拟化性能较低,半虚拟化又需要修改客户操作系统(全虚拟化和半虚拟化后面讲),但操作系统级虚拟化就几乎没有开销。以上几个特性使操作系统级虚拟化非常适合云计算场景。

一个典型的代表是Docker,其基于Linux的LXC,说白了就是cgroups。Docker最近两年火得不要不要的,但实际上不是新鲜事物,而且一旦用上Docker就需要传统的运维体系有巨大的变革,因此在大企业中很少见到用得好的(这个话题大了,以后再详细讲)。Docker的优点就是上述操作系统级虚拟化的优点,缺点也很明显,首先宿主机和虚拟机都只能是linux,资源隔离比VMware这些也有差距,cpu和disk的管理较简单。(当然在Docker间共享数据还是很容易的,用数据卷就行了,我不懂Docker都知道这玩意儿,上周一批懂Docker的砖家一起开会都没想到这东西,我也是醉鸟)

库支持级:

这种方案基于一个思路,大部分应用都是基于用户库API而不是系统级调用的,因此可以通过API钩子控制应用程序和其他系统部分之间的连接,使得带有库接口的虚拟化成为可能。这种方式和网游脱机外挂其实异曲同工,难度是不高的。

一个典型的代表是WINE,其可以在Unix like系统上运行win32应用程序。当然其实是非常难用的,高中刚开始玩linux那会儿,总想着用WINE跑win上的游戏,但是除了一些简单的exe可以运行,directx游戏都是跑不了的,原因是DLL依赖太复杂了,很多也不支持。这么多年过去了问题越来越恶化,毕竟微软几千号人写API,WINE的开发就那么几个,模拟得过来么。

应用程序级:

这个级别的虚拟化是将一个应用程序虚拟化为一个虚拟机。最流行的方法是高级语言虚拟机,在这种情况下,虚拟化层作为一个应用程序处于操作系统之上,并且这一层抽象出一个虚拟机,其可以运行为特定的机器环境所编写和编译的程序。

典型的代表是Java虚拟机和微软的.Net CLR,当然因为纯应用程序级虚拟化效率很低,两者现在都不是纯的虚拟机,比如JVM中很关键的一部分就是JIT(即时编译),当年Java1.0时代的纯解释执行才等同于应用程序级虚拟机,那个效率谁用谁知道。

以下是五种级别的对比,*越多越好(性能高,灵活性高,实现复杂度低,隔离性好):

实现级别 高性能 应用程序灵活性 实现复杂度 应用程序隔离性
应用程序级 ** ** * *****
库支持(用户级API)级 *** ** **** **
操作系统级 ***** ** *** **
硬件抽象级 ***** *** * ****
指令集体系结构级 * ***** *** ***

2.机制

可根据是否需要修改客户操作系统,分为硬件虚拟化和编译器支持虚拟化。硬件虚拟化又分为:全虚拟化和基于主机的虚拟化(很多材料将两者等同,是不对的)。编译器支持虚拟化只有一种,称为半虚拟化。

全虚拟化:

在全虚拟化中,非关键指令直接运行在硬件之上,而关键指令(特权指令、控制敏感指令、行为敏感指令)被替换为通过软件模拟的陷入VMM/hypervisor的指令。即,(非x86系统中)VMM运行在环0,客户操作系统运行在环1,用户应用程序运行在环3,用户应用程序的指令直接操作系统硬件,客户操作系统的指令通过VMM二进制翻译后操作系统硬件。见下图。VMware就使用了这种机制。

基于主机的虚拟化:

这种机制是,宿主机的操作系统仍旧负责管理硬件,在宿主机操作系统上安装一个虚拟化层,客户操作系统安装并运行在虚拟化层之上。可见这种机制下不论何种指令,都需要经虚拟化层转发后由宿主机操作系统执行,并且当客户操作系统的ISA与底层硬件的ISA不同时,还需要在虚拟化层做二进制翻译,因此效率是很低的。也可见这种方式和全虚拟化是有区别的,所以必须分开讲。

半虚拟化:

半虚拟化技术是后来才出现的技术,也叫做准虚拟化技术,现在比较热门,它就是在全虚拟化的基础上,把客户操作系统进行了修改,增加了一个专门的API,这个API可以将客户操作系统发出的指令进行最优化,即不需要VMM/Hypervisor耗费一定的资源进行翻译操作,因此Hypervisor的工作负担变得非常的小,整体性能也有很大的提高。不过缺点就是,要修改包含该API的操作系统,但是对于某些不含该API的操作系统(主要是windows)来说,就不能用这种方法。半虚拟化技术见下图。

这些都说完,就可以来比较另两种主流的虚拟化技术了:XEN和KVM。

XEN(参见 http://baike.baidu.com/link?url=J97539DMsA9HW2WZYsX7ZNliZUx9d2j3LarHw2yRd37Lh_ho6zAe1Gy5Xfh-z-TxuLH3Q6T2qfrNEBDmuMiAca)主要是为x86平台服务的,当运行修改的操作系统时可以使用半虚拟化机制,当CPU支持且操作系统无法修改时可使用全虚拟化机制。

KVM(参见http://baike.baidu.com/link?url=kV4fSyYs0tw-bhBpp6Fofh4C6c5nQDKmY1eTmIR-BPbliDsX0uYOF97ypPAsCqmsM96xt85ai4q89rO8XaEe8_,这里说KVM是全虚拟化,又是错的)不针对特定架构,但针对特定宿主操作系统,因为它是linux内核2.6.20后内置的,代码量比XEN少得多。当运行修改的操作系统时使用半虚拟化机制,当CPU支持时可使用改进的基于主机的虚拟化机制,即Hypervisor虽然位于主操作系统上,但在内核上打了个洞,如果CPU支持如Intel
VT之类的技术,虚拟机操作系统的关键指令可直接映射到物理硬件上,从而大大提升性能,如图所示(盗自 http://www.linuxidc.com/Linux/2015-03/114462.htm )。

如果硬要比较的话,在编译器支持虚拟化(半虚拟化)时XEN优于KVM,在硬件虚拟化时KVM优于XEN。

(本文参考《云计算与分布式系统》,但是原书的相关章节有些混乱,也有一些跟不上形势的地方,一并修改了)

时间: 2024-11-03 14:52:49

虚拟化的层次与机制的相关文章

(13)虚拟化技术之服务器虚拟化

1.服务器虚拟化的层次 服务器虚拟化分为寄居虚拟化和裸机虚拟化两种 (1)寄居虚拟化的层次: 寄居虚拟化的虚拟化层一般称为虚拟机监控器(VMM) 这类虚拟化架构系统损耗比较大 就操作系统层的虚拟化而言,没有独立的Hypervisor层 如果使用操作系统层虚拟化,所有虚拟服务器必须运行同一操作系统 (2)裸机虚拟化的层次 架构中的VMM也可以认为是一个操作系统,一般称为Hypervisor Hypervisor实现从虚拟资源到物理资源的映射 Hypervisor实现了不同虚拟机的运行上下文保护与切

持续集成方案

大纲 构建 版本控制 部署 单元测试 架构文档化 命名约定 数据库伸缩性 自动化 反馈 实践 引言: 持续集成的前身: 在使用持续集成之前,很多开发团队都是用每日构建(nightly build).当时,微软使用这个实践很多年了.谁破坏了构建,就要负责监视后续的构建构成,直至发现下一个破坏了构建的人. 为什么要使用持续集成? 对于大多数项目来说,采纳持续集成实践是向高效率和高质量迈进的一大步.它保证那些创建大型复杂系统的团队具有高度的自信心和控制力.一旦代码提交引入了问题,持续集成就能为我们提供

OpenStack Days China参会有感——GIS距主流IT还有多远

前几天有幸参加了OpenStack Days China的两天技术峰会,集合了全球及国内顶尖的OpenStack技术专家,为我们分享了许多关于OpenStack的技术报告. 有许多人参加类似技术峰会都有这些感受: 1.一般主会场的领导和院士发言基本没有什么干货,也就是对我们实际工作没有太大帮助 2.一般讲的不错的都是公司的CEO.CTO等,但是他们都是公司商业因素占据很多,技术并不是他们实干,好像也没有什么收获 3.一般分享干货的实践者往往讲的水平一般,枯燥乏味,太干了,干的让人无法消化 当然,

网络工程师眼中的docker

好多年前,"云计算"这个名词刚出现的时候,好多概念还真是"云里雾里"."虚无缥缈",好多时候,大家把"云计算"等同于"网格计算"."分布式计算".似乎那个时候更注重是"计算"两字,或者可以说那个时候大家对云的理解还不够透彻,不知道"云"到底是啥玩意.又过了几年,"云计算"的概念清晰了许多,好多人认为"虚拟化"

windows安全行业功能体系

文章转载与看雪论坛. 我觉得,做一个杀毒软件,大概要有以下的驱动程序.下面我给出了杀毒软件的大致设计框架.由于一些事情的存在,程序代码暂时不能上传到看雪论坛上,以免引起日后产生不必要的法律纠纷.这里还请各位朋友能够原谅. 若有不对和不足的地方,还请见谅. 1)磁盘扫描计算机病毒. 一个扫描引擎主要包含:扫描规则设置.对象设置.扫描规则设置主要是,允许用户使用一个或全部规则对文件进行扫描.扫描对象设置主要是,允许用户对要扫描的文件的类型进行设置. <1>判断是否是PE 文件格式.若打开的文件不是

IOFlow——从微软的角度看Software Defined Storage

         note:网上有很多关于软件定义存储的负面消息.有人说,在存储发展的历史中,存储早就不仅仅是硬件了,软件在存储中有一个核心的地位:还有人觉得应该做软件隐藏的存储,因为软件这个事让存储的管理变得很难,这些软件包括:重复数据删除,自动精简配置等:也有些人说,我们并不需要更多的软件,我们需要看到的是更少的软件:也有人说,存储本来就是软件定义的,所有的存储都需要软件:尤其是当存储成为分享资源时(大数据和数据中心的存储),往往会被复杂而神秘的软件包围.很多人说,每次更新系统时,就会增加越

容器(Container)

Container发展史: 早在1982年,Unix系统内建的chroot机制也是一种Container技术.其他如1998年的FreeBSD jails.2005年出现的Solaris Zones和OpenVZ,或像是Windows系统2004年就有的Sandboxie机制都属于在操作系统内建立孤立虚拟执行环境的作法,都可称为是Container的技术.直到2013年,dotCloud这家PaaS服务公司开源释出了一套将Container标准化的平台Docker,大受欢迎,所以,dotClou

在 Ubuntu16.04上安装并使用Docker

介绍 Docker是一个开放源代码软件项目,让应用程序布署在软件容器下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制[1].Docker利用Linux核心中的资源分脱机制,例如cgroups,以及Linux核心名字空间(name space),来创建独立的软件容器(containers).这可以在单一Linux实体下运作,避免引导一个虚拟机造成的额外负担[2].Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括进

XenGT为什么会比GRID vGPU先实现基于vGPU的在线迁移呢?

在最近的XenSummit 2016上,英特尔在一个Session上演示了基于Xen的GPU虚拟化在线迁移.为什么后起之秀会吊打老司机? 一.XenGT如何实现在线迁移? 我们先来看XenGT的架构 1.英特尔的显卡集成到CPU上,使用的显存是内存,和CPU共同访问内存空间: 2.在hypervisor实现对GPU的陷阱(trap)和透传(pass-through)机制,说明意思呢?就是说和CPU虚拟化类似的思路,特权的指令交由hypervisor,这些指令有虚拟机传递下来后被拦截,交由hype