目录

  1. 引子
  2. 形形色色的虚拟化
    1. 硬件抽象层上的虚拟化
    2. 操作系统层上的虚拟化
    3. 库函数层上的虚拟化
    4. 编程语言层上的虚拟化
  3. 系统虚拟化
  4. 系统虚拟化简史
  5. 系统虚拟化的好处
    1. 封装性
    2. 多实例
    3. 隔离
    4. 硬件无关性
    5. 特权功能

引子

虚拟化(Virtualization),抽象来说,虚拟化是资源的逻辑表示,它不受物理限制的约束。具体来说,虚拟化技术的实现形式就是在系统中加入一个虚拟化层,虚拟化层将下层的资源抽象成另一种形式的资源,提供给上层使用。通过空间上的分割、时间上的分时以及模拟,虚拟化可以将一份资源分成多份。反过来,虚拟化也可以将多份资源抽象成一份。总的来说,虚拟化可以把一个纷繁复杂、无计划性的世界改造成一个似乎是为人们特定需求而量身打造的世界。

形形色色的虚拟化

现代计算机系统是一个庞大的整体,整个系统的复杂性是不言而喻的。因而,计算机系统被分成了多个自下而上的层次。下图所示的是一种常见的计算机系统中的抽象层。每一层都向上一层呈现一个抽象,并且每一层只需要知道下层抽象的接口,而不需要了解其内部运行机制。这样,以层的方式抽象资源的好处是每一层只需要考虑本层设计以及与相邻层间的交互,从而大大降低了系统设计的复杂性,提高了软件的移植性。


计算机系统的各个抽象层计算机系统的各个抽象层

在硬件与操作系统之间的是硬件抽象层,在操作系统与应用程序或函数库之间的是API抽象层。硬件抽象层(Hardware Abstraction Layer,HAL)是计算机软件所能控制的硬件的抽象接口,通常包括CPU的各种寄存器、内存管理模块、I/O端口和内存映射的I/O地址等。API抽象层抽象的是一个进程所能控制的系统功能的集合,包括创建新进程、内存申请和归还、进程间同步与共享、文件系统和网络操作等。

本质上,虚拟化就是由位于下层的软件模块,通过向上一层软件模块提供一个与它原先所期待的运行环境完全一致的接口的方法,抽象出一个虚拟的软件或者硬件接口,使得上层软件可以直接运行在虚拟的环境上。

在虚拟化中,物理资源通常称为宿主(Host),而虚拟出来的资源通常称为客户(Guest)。由此衍生出几个概念。将一台物理计算机虚拟为一个或多个虚拟计算机,则这个物理计算机通常被称为宿主机(Host Machine),而其上运行的虚拟机被称为客户机(Guest Machine)。宿主机上如果有操作系统,通常称为宿主机操作系统(Host OS),而虚拟机中运行的操作系统被称为客户机操作系统(Guest OS)。

硬件抽象层上的虚拟化

硬件抽象层上的虚拟化是指通过虚拟硬件抽象层来实现虚拟机,为客户机操作系统呈现和物理硬件相同或相近的硬件抽象层。由于客户机操作系统所看到的是硬件抽象层,因此,客户机操作系统的行为和在物理平台上没有什么区别。通常来说,宿主机和客户机的ISA(Instruction Set Architecture,指令集架构)是相同的,客户机的大部分指令可以在宿主机处理器上直接运行。只有那些需要虚拟化的指令才会由虚拟化软件进行处理,从而大大降低了虚拟化开销。此外,客户机和宿主机的硬件抽象层的其他部分如中断控制器、设备等,可以是完全不同的,当客户机对硬件抽象层进行访问时,虚拟化软禁需要对此进行截获并模拟。比较知名的硬件抽象层上的虚拟化有VMware、Xen等。

操作系统层上的虚拟化

操作系统层上的虚拟化是指操作系统的内核可以提供多个相互隔离的用户态实例。这些用户态实例(经常被称为容器)对于它的用户来说就是像是一台真实的计算机,有自己独立的文件系统、网络、系统设置和库函数等。从某种意义上来说,这种技术可以被认为是UNIX系统chroot命令的一种延伸。因为这是操作系统内核主动提供的虚拟化,因此操作系统层上的虚拟化通常非常高效,它的虚拟化资源和性能开销非常小,也不要需要有硬件的特殊支持。但它的灵活性相对较小,每个容器中的操作系统通常必须是同一种操作系统。另外,操作系统层上虚拟化虽然为用户态实例之间提供了比较强的隔离性,但其粒度是比较粗的。

因为操作系统层上虚拟化的高效性,它被大量应用在虚拟主机服务环境中。比较有名的操作系统级虚拟化解决方案有Paralles的Virtuozzo,Solaris的Zone和Linux的VServer等。

库函数层上的虚拟化

操作系统通常会通过应用级的库函数提供给应用程序一组服务,例如文件操作服务、时间操作服务等。这些库函数可以隐藏操作系统内部的一些细节,使得应用程序编程更为简单。不同的操作系统库函数有着不同的服务接口,例如Linux的服务接口是不同于Windows的。库函数层上的虚拟化就是通过虚拟化操作系统的应用级库函数的服务接口,使得应用程序不需要修改,就可以在不同的操作系统中无缝运行,从而提高系统间的互操作性。例如,WINE系统是在Linux上模拟了Windows的库函数接口,使得一个Windows的应用程序能够在Linux上正常运行。

编程语言层上的虚拟化

另一大了编程语言层上的虚拟机称为语言级虚拟机,例如JVM(Java Virtual Machine)和微软的CLR(Common Language Runtime)。这一类虚拟机运行的是进程级的作业,所不同的是这些程序所针对的不是一个硬件上存在的体系结构,而是一个虚拟体系结构。这些程序的代码由虚拟机的运行时支持系统首先翻译为硬件的机器语言,然后再执行。通常一个语言类虚拟机是作为一个进程在物理计算机系统中运行的,因此,它属于进程级虚拟化。

系统虚拟化

系统虚拟化是指将一台物理计算机系统虚拟化为一台或多台虚拟计算机系统。每个虚拟计算机系统(简称虚拟机)都拥有自己的虚拟硬件(如CPU、内存和设备等),来提供一个独立的虚拟机执行环境。通过虚拟化层的模拟,虚拟机中的操作系统认为自己仍然是独占一个系统在运行。每个虚拟机中的操作系统可以完全不同,并且它们的执行环境完全是独立的。这个虚拟化层被称为虚拟机监视器(Virtual Machine Monitor,VMM)。如下图所示。

系统虚拟化系统虚拟化

从本质上来说,虚拟计算机系统和物理计算机系统可以是两个完全不同的ISA的系统。不同的ISA使得虚拟机的每一条指令都需要在物理机上模拟执行,从而造成性能上的极大下降。同样的,相同体系结构的系统虚拟化通常会有比较好的性能,VMM实现起来也会比较简单。虚拟机的大部分指令可以在处理器上直接运行,只有那些需要虚拟化的指令才会由VMM进行处理。

1974年,Popek和Goldberg定义了虚拟机可以看作是物理机的一种高效隔离的复制。上面的定义里蕴含了三层含义(同质、高效和资源受控),这也是一个虚拟机所具有的三个典型特征。

  • 同质,是指虚拟机的运行环境和物理机的环境在本质上需要是相同的,但是在表现上能够有一些差异。例如,虚拟机所看到的处理器的个数可以和物理机上实际的处理器个数不同,处理器主频也可以与物理机的不同,但是物理机上和虚拟机中看到的处理器必须是同一种基本类型的。

  • 高效,是指虚拟机中运行的软件需要有接近在物理机上直接运行的性能。为了能做到这一点,软件在虚拟机中运行时,大多数的指令需要直接在硬件上执行,只有少量指令需要经过VMM处理或模拟。

  • 资源受控,是指VMM需要对系统资源有完全控制能力和管理权限,包括资源的分配、监控和回收。

系统虚拟化最早出现于20世纪60年代的IBM System360上。经过一段时间的沉寂后,相同ISA的系统虚拟化从20世纪90年代开始再次取得长足的发展,不论从硬件还是软件上都涌现出很多技术和解决方案。

系统虚拟化简史

历史上第一个虚拟机是1965年左右IBM公司开发的System/360 Model 40 VM。其最初的设计目的是将最先进的虚拟内存的概念延展到计算机的其他子系统,搭建一个时分共享的系统,运行多个单用户的操作系统,以实现多个用户对昂贵物理计算机资源的共享。

之后,随着时分多用户操作系统的发展,虚拟化技术真正成熟是在15年后的IBM VM/370系统率中。作为一个标志性的系统,VM/370的许多原理至今还在IBM的z系列大型机上使用。VM/370运行在IBM System/370大型机上,并虚拟出同体系结构的System/370虚拟机。由于System/370硬件的优秀设计,对VM/370的实现提供完整而高效的支持,以VM/370为代表的虚拟机和系统徐计划技术完整实现了虚拟机的思想。但是,由于其应用于大型机上,并面临的问题与背景和目前的服务器与个人计算机环境有所不同,因此和这里介绍的系统虚拟化技术不同,为了区分两者,把前者称为传统虚拟化或经典系统虚拟化。

传统系统虚拟化是完全虚拟化(Full Virutalization),它所抽象的虚拟计算机具有完全的物理特性。这里不得不提一下另一个出现在同一时代,事实上还略早的概念——部分虚拟化(Partial-virtualization)。部分虚拟化最早出现在IBM M44/44X系统中,它提供了对底层硬件的部分模拟,以满足某些专门的软件的执行环境,但是并不能运行所有可能运行在物理机上的软件。部分虚拟化技术的出现直接导致其后虚拟化技术的出现。

伴随着硬件的发展,从20世纪90年代后期开始,台式计算机的性能逐渐达到支持多个系统同时运行的水平。在大型机上沉寂一时的虚拟化技术,在小型机和微机领域开始迅速升温。1997年,在斯坦福大学开发的Disco系统中探索了在共享内存大小的大规模处理器系统上运行普通的桌面操作系统。基于Disco系统的研究经验,Disco开发者们继续进行了个人计算机上虚拟化技术的研究,之后就有了1998年VMware公司的诞生。

在个人计算机领域广泛使用的x86体系结构的先天设计,存在系统虚拟化的支持缺陷或虚拟化漏洞(Virtualization Hole)。在x86体系结构上的虚拟化技术,都需要用软件的方法来弥补体系结构设计上的不足。例如,采用代码扫描与修补方法(Scan-and-patch)或二进制代码翻译(Bianry Translation)技术来实现基于软件的完全虚拟化。但这样做势必带来性能上的损失以及非常大的软件复杂度。

在这种情况下,学术界提出了另一种思路来克服体系结构上的缺陷,叫做类虚拟化技术(Para-Virtualization)。其主要思想是通过客户机操作系统与虚拟化管理层的协同设计,由虚拟化管理层软件提供一个近似于原物理系统,但又不完全相同(与原系统)的虚拟平台,以避免虚拟化漏洞和实现更高的虚拟化效率。虚拟化技术需要修改操作系统的源代码来与下层的虚拟化管理层软件协同工作,从而避免体系结构上的缺陷。美国华盛顿州大学的Denali项目和源自英国剑桥大学的Xen项目都支持类虚拟化。

虽然上述两种基于软件的方法都能够实现系统虚拟化,但是它们各自存在不可回避的问题。基于软件的完全虚拟化方法不可避免地会导致性能上的下降,同时伴随一些兼容性上的损失。而修改操作系统的发放对于现有系统的移植和伴随着内核升级的维护提出了要求,并且它对非开源的操作系统也有局限性。

从根本上解决体系结构上的缺陷,最好的办法是从体系结构本身入手。Intel公司和AMD公司在2006年以后都逐步推出了带有硬件虚拟化支持的处理器,如Intel公司的Virtualization Technology(VT)技术和AMD公司的Secure Virtual Machine(SVM)技术,从根本上保证了x86架构是一个可虚拟化的架构。Intel公司和AMD公司采用的是硬件辅助的完全虚拟化策略。Intel公司的VT技术和AMD公司的SVM技术弥补了x86体系结构上的漏洞。操作系统不需要做任何修改就可以运行在虚拟机中。VMM软件可以利用这些硬件虚拟化技术,这样软件的实现就可以极大的简化,并且也更为高效和安全。

今天的大部分服务器和台式机处理器都己经有了对虚拟化的支持,但这只是解决了处理器层如何更好地支持虚拟化问题。为了使虚拟化解决方案更加高效(例如I/O虚拟化),计算机系统的各个层次都在逐渐加入对虚拟化的硬件支持,逐渐形成一个对虚拟化更好支持的虚拟化生态系统。以Intel为例,除了处理器中的VT技术之外,芯片组中开始提供针对I/O虚拟化功能的VT-d技术,网卡中可开始提供更好的网络虚拟化支持的多队列的VMDq技术等。与此同时,PCI标准组织也在积极地定制在PCI设备级对虚拟化进行支持的单根PCI桥IOV(Single Root IOV,SR-IOV)和多根PCI桥IOV(Multi-Root IOV,MR-IOV)标准。

系统虚拟化的好处

系统虚拟化提供了多个隔离的执行环境,这种将运行环境完整封装起来带来的好处是很多的。

封装性

以虚拟机为粒度的封装使得虚拟机运行环境的保存非常便捷。虚拟机的优秀封装性使得以下应用模式可以很方便地实现。

  1. 虚拟机快照(Snapshot)。将运行中的一个虚拟机的某个时间点的状态抓取下来,就像抓拍一张照片一样。
  2. 虚拟机克隆(Clone)。从一个虚拟机的执行环境复制出一个或多个相同的虚拟机。
  3. 虚拟机挂起(Suspend)。指暂停一个运行中的虚拟机,将其运行环境保存在磁盘上。与之相反,虚拟机恢复(Resume)是指将保存在磁盘上的虚拟机运行环境恢复到内存中以继续运行的操作。

优秀的封装性使得虚拟机的保存更容易,从而在灾难恢复中发挥更大的作用。虚拟机快照和克隆等使得部署各种软件运行环境更容易,从而是软件开发的测试和调试更为快捷方便。虚拟化最早起源于服务器虚拟化,目前桌面虚拟化也逐渐开始在企业环境中发展起来。优秀的封装性使得企业中可以方便地进行桌面软件维护管理,从而大大降低了IT的管理维护成本。

多实例

在一个计算机上运行多个虚拟机使得资源的调度更为优化。不同的虚拟机有不同的繁忙和空闲时段,忙闲交错使得单个计算机系统的系统资源利用率大大提高。出于上述原因,产业界大力推广了服务器整合(Server Consolidation),使得多个物理服务器合并到少数几个计算机上,作为虚拟机来运行。这可以用更少的服务器获得同样的整体性能,并大大提高计算机性能的利用率。伴随着处理器性能的不断提升,特别是多核时代到来后,虚拟化的服务器整合比也在不断提高。由于虚拟化技术拥有高效、节能省电和节省空间等多种优势,无论是大型企业数据中心整合还是中心型企业的经济型服务器选型,虚拟化都可以在其中扮演着重要的角色。事实上,实施服务器虚拟化可以让客户获得更大的利益。虚拟化技术能够为公司节约大量的成本,降低了系统管理成本,节约人力,提高旧业务系统的性能,还降低了新系统的开发部署成本。

隔离

尽管不使用虚拟化也可以对不同的工作负载进行整合,但是虚拟机所具有的隔离性可以提供一些重要的特性。使用虚拟机,每个应用成熟可以在自己的操作系统环境中独立地运行,而不会影响到其他的工作负载。例如,如果一个虚拟机的操作系统由于故障或受到恶意破坏而崩溃了,其他虚拟机中的应用程序仍然可以继续正常运行。故障或破坏被天然地封闭在一个虚拟机中。

这种隔离性支持多个用户在同一台物理服务器上对不同的应用程序进行独立的操作。例如,虚拟机所提供的隔离特性非常适合于测试场景,支持并行的和隔离的执行多项测试。同时,这种隔离性对于系统安全十分重要,也是安全软件公司利用虚拟机作为诱饵吸引攻击的原因之一。

硬件无关性

虚拟化是资源的逻辑表示,它不受物理限制的约束。由于虚拟化层的抽象,虚拟机与底层的硬件没有直接的绑定关系。因此,尽管目前计算机体系结构呈现出很大的异构性,但只要另一台计算机提供相同的虚拟硬件抽象层,一个虚拟机就能够无缝地迁移过去。虚拟机迁移是虚拟化技术中的亮点之一。

有了虚拟机的迁移,硬件的维护就不必每次都关闭计算机了。在一台计算机需要硬件维护时,其中运行的虚拟机能够迁移到其他计算机上,等维护工作结束后再迁移回来。在集群中一些计算机工作量比较大而一些计算机比较空闲的情况下,一部分运行在繁忙的计算机上的虚拟机能够迁移到较空闲的计算机上。

另外,虚拟硬件抽象层不需要与物理硬件相匹配,因而还可以虚拟出比较旧的硬件来兼容旧系统软件。

特权功能

由于虚拟化层处于客户机及客户机操作系统的下面,其具有更高的特权级。在这个层中添加新的功能有如下两个优势。

  1. 新的功能有高特权级,不能被客户机操作系统绕过。
  2. 新的功能不需要了解客户机内部的语义,使其实现上更容易。

目前,在研究和工业领域已经有大量基于虚拟化特权功能特性的研究和应用。

事件记录与回放(Log and Replay)在虚拟化层中能够很方便地实现,因为虚拟化层截获并传递所有系统级事件。

入侵检测(Intrusion Detection)也是在虚拟化层中添加的功能之一。利用虚拟化层所在的特权级别,入侵检测系统能够保证其检测不会被客户机绕过,同时客户机也不会知道这个服务的存在。

病毒检测等安全防范机制同样也能够在虚拟化层中实现,其好处是不需要担心检测系统自身的安全,客户机中的病毒很难攻击到下层,甚至不会知道自身是运行在客户机中。另一个好处是检测不会被上层客户机绕过。