云计算虚拟化技术

原文:虚拟化技术的分类及介绍,有删减。

虚拟化是云计算系统中的一种基础技术,可以说当前一个云计算服务必定是构建在虚拟化的基础上的。

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

本质上,虚拟化就是由位于下层的软件模块,通过向上一层软件模块提供一个与它原先所期待的运行环境完全一致的接口的方法,抽象出一个虚拟的软件或硬件接口,使得上层软件可以直接运行在虚拟的环境上。虚拟化可以发生在现代计算机系统的各个层次上,不同层次的虚拟化会带来不同的虚拟化概念。

虚拟化技术起始于IBM370体系结构,经过四十余年的发展,当前存在诸多实现在不同层次的虚拟化技术,原理不尽相同,且每一种技术都相当复杂。血衫整理了一些资料,大部分来源于本文开头提到的文章——虚拟化技术的分类及介绍,对目前存在的较流行的虚拟化技术进行分类,并对其原理进行初步介绍,以便对纷繁复杂的虚拟化技术有个整体认识,厘清不同虚拟化技术之间的相互关系。

零、虚拟化的分类

在虚拟化的语境中,物理资源通常有一个定语称为宿主(Host),而虚拟出来的资源通常有一个定语称为客户(Guest)。

在计算机系统中,从底层至高层依次可分为:

  1. 硬件层
  2. 操作系统层
  3. 函数库层
  4. 应用程序层

在对某层实施虚拟化时,该层和上一层之间的接口不发生变化,而只变化该层的实现方式。

从使用虚拟资源的Guest的角度来看,虚拟化可发生在上述四层中的任一层。

应当注意,在对Guest的某一层进行虚拟化时,并未对Host在哪一层实现它作出要求,这一点是时常引起混淆的地方。

一、硬件层虚拟化/系统级虚拟化

实现在此层的虚拟化技术可以对整个计算机系统进行虚拟,即可将一台物理计算机系统虚拟化为一台或多台虚拟计算机系统,故又可称作系统级虚拟化。

每个虚拟计算机系统(简称为虚拟机)都拥有自己的虚拟硬件(如CPU、内存和设备等),来提供一个独立的虚拟机执行环境。

每个虚拟机中的操作系统可以完全不同,并且它们的执行环境是完全独立的。由于客户机操作系统所能看到的是硬件抽象层,因此,客户机操作系统的行为和在物理平台上没有什么区别。

在每台虚拟机中都有属于它的虚拟硬件,通过虚拟化层的模拟,虚拟机中的操作系统认为自己仍然是独占一个系统在运行,这个虚拟化层被称为虚拟机监控器(Virtual Machine Monitor,VMM)。VMM对物理资源的虚拟可以归结为三个主要任务:处理器虚拟化、内存虚拟化和I/O虚拟化。其中,处理器虚拟化是VMM中最核心的部分,因为访问内存或进行I/O本身就是通过一些指令来实现的。

系统级虚拟化又可以按照实现方法分类和实现结构进行:

  • 实现方法

    如果一个体系结构上存在敏感指令不属于特权指令,那么其就存在虚拟化漏洞。从解决虚拟化漏洞的实现方法出发分为如下三类:

    • 仿真(Bochs),所有指令都采用模拟来实现,就是取一条指令,就模拟出这条指令执行的效果。这种方法称作仿真。使用仿真方法的主要问题是速度会非常慢。由于每条指令都必须在底层硬件上进行仿真,因此速度减慢100倍的情况也并不稀奇。

    • 完全虚拟化,无须对操作系统进行任何修改,因此这种方式被称为完全虚拟化。

      Intel的VT-x和AMD的AMD-V是这一方向的代表。以VT-x为例,其在处理器上引入了一个新的执行模式用于运行虚拟机,当虚拟机执行在这个特殊模式中时,它仍然面对的是一套完整的处理器寄存器集合和执行环境。

      完全虚拟化的任何敏感操作都会被处理器截获并报告给VMM,以此来避免虚拟化漏洞,典型的有知名的产品有:

      • VirtualBox
      • KVM
      • VMware Workstation和VMware vSphere
      • Xen
    • 类虚拟化/半虚拟化(Xen和微软的Hyper-V),通过修改操作系统内核的代码,使得操作系统内核完全避免这些难以虚拟化的指令,避免了虚拟化漏洞。

      类虚拟化可以自定义出高度优化的协议I/O。这种I/O协议完全基于事务,可以达到近似物理机的速度。

  • 实现结构

    从Host实现VMM(是否偷懒?)的角度出发,还可以将当前主流的虚拟化技术按照实现结构分为如下三类:

    • Hypervisor模型(VMware vSphere)

      在早期计算机界,操作系统被称为Supervisor,因而能够在其他操作系统上运行的操作系统被称为 Hypervisor。在Hypervisor模型中,VMM首先可以被看做是一个完备的操作系统,不过和传统操作系统不同的是,VMM是为虚拟化而设计的,因此还具备虚拟化功能:

      • 所有的物理资源如处理器、内存和I/O设备等都归VMM所有,因此,VMM承担着管理物理资源的责任
      • VMM需要向上提供虚拟机用于运行客户机操作系统,因此,VMM还负责虚拟环境的创建和管理。

      由于设备驱动开发的工作量是很大的,在实际的产品中,基于Hypervisor模型的VMM通常会根据产品定位,有选择地挑选一些I/O设备来支持,而不是支持所有的I/O设备。

    • 宿主模型(KVM、VirtualBox和VMware Workstation)

    在宿主模型中,物理资源由宿主机操作系统管理。VMM通常是宿主机操作系统独立的内核模块。 VMM通过调用宿主机操作系统的服务来获得资源, 实现处理器、内存和I/O设备的虚拟化。VMM创建出虚拟机之后,通常将虚拟机作为宿主机操作系统的一个进程参与调度。

    由于物理资源由宿主机操作系统控制,因此,VMM虚拟化的效率和功能会受到一定影响。

    安全方面,由于VMM是宿主机操作系统内核的一部分,虚拟机的安全不仅依赖于VMM的安全,也依赖于宿主机操作系统的安全。

    • 混合模型(Xen)

    混合模型是上述两种模式的汇合体。VMM依然位于最低层,拥有所有的物理资源,但VMM 会主动让出大部分I/O设备的控制权,将它们交由一个运行在特权虚拟机中的特权操作系统控制。相应地,VMM 虚拟化的职责也被分担.处理器和内存的虚拟化依然由VMM来完成,而I/O的虚拟化则由VMM和特权操作系统共同合作来完成。

    混合模型集中了上述两种模型的优点。 VMM可以利用现有操作系统的I/O设备驱动程序,不需要另外开发。VMM直接控制处理器、内存等物理资源,虚拟化的效率也比较高。

    采用这种模型的典型是。

另外,不是所有处理器架构都能够虚拟化的。

相同体系结构的系统虚拟化通常会有比较好的性能,并且VMM实现起来也会比较简单。这种情况下虚拟机的大部分指令可以在处理器上直接运行,只有那些与硬件资源关系密切的敏感指令才会由VMM进行处理。

此时面前的一个问题是,要能将这些敏感指令很好地筛选出来。但事实上,某些处理器在设计之初并没有充分考虑虚拟化的需求,导致没有办法识别出所有的敏感指令,因而不具备一个完备的可虚拟化结构。

为了VMM可以完全控制系统资源,它不允许虚拟机上操作系统直接执行敏感指令。如果一个系统上所有敏感指令都是特权指令,则能够用一个很简单的方法来实现一个虚拟环境:将VMM运行在系统的最高特权级上,而将客户机操作系统运行在非最高特权级上,当客户机操作系统因执行敏感指令而陷入到VMM时,VMM模拟执行引起异常的敏感指令。

判断一个架构是否可虚拟化,其核心就在于该结构对敏感指令的支持上。如果一个架构中所有敏感指令都是特权指令,则称其为可虚拟化架构,否则称为不可虚拟化架构。

在x86架构中,所有的特权指令都是敏感指令,然而并不是所有的敏感指令都是特权指令。

二、操作系统层虚拟化

操作系统层上的虚拟化是指操作系统的内核可以提供多个互相隔离的用户态实例。这些用户态实例(经常被称为容器)对于它的用户来说就像是一台真实的计算机,有自己独立的文件系统、网络、系统设置和库函数等。

由于这是操作系统内核主动提供的虚拟化,因此操作系统层上的虚拟化通常非常高效,它的虚拟化资源和性能开销非常小,也不需要有硬件的特殊支持。

但它的灵活性相对较小,每个容器中的操作系统通常必须是同一种操作系统。另外,操作系统层上的虚拟化虽然为用户态实例间提供了比较强的隔离性,但其粒度是比较粗的。

在操作系统虚拟化技术中,每个节点上只有唯一的系统内核,不虚拟任何硬件设备。通过使用操作系统提供的功能,多个虚拟环境之间可以相互隔离。

通常所说的容器(Container)技术,如目前为止最流行的容器系统Docker,即属于操作系统级虚拟化。

相比较于硬件层虚拟化,操作系统层虚拟化有以下优点:

  • 操作系统领域一直以来面临的一个主要挑战来自于应用程序间的相互独立性和资源共享之间的矛盾,即每个应用程序都希望能运行在一个相对独立的系统环境下,不受到其他程序的干扰,同时又能以方便快捷的方式与其他程序交换和共享系统资源。

    当前通用操作系统更强调程序间的互操作性,而缺乏对程序间相对独立性的有效支持,然而对于许多分布式系统如Web服务、数据库、游戏平台等应用领域,提供高效的资源互操作同保持程序间的相对独立性具有同等重要的意义。

    主流虚拟化产品VMware和Xen等均采用Hypervisor模型。该模型通过将应用程序运行在多个不同虚拟机内,实现对上层应用程序的隔离。但由于Hypervisor 模型倾向于每个虚拟机都拥有一份相对独立的系统资源,以提供更为完全的独立性,这种策略造成处于不同虚拟机内的应用程序间实现互操作非常困难。例如, 即使是运行在同一台物理机器上,如果处于不同虚拟机内,那么应用程序间仍然只能通过网络进行数据交换,而非共享内存或者文件。而如果使用容器技术,由于各容器共享同一个宿主操作系统,能够在满足基本的独立性需求的同时提供高效的系统资源共享支持。

  • 容器技术还可以更高效地使用系统资源,由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

  • 容器还具有更快速的启动时间,传统的虚拟机技术启动应用服务往往需要数分钟,而对于容器由于,直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间,大大的节约了应用开发、测试、部署的时间。

操作系统级的虚拟化实现包括:

  1. chroot

    容器的概念始于 1979 年的 UNIX chroot,它是一个 UNIX 操作系统上的系统调用,用于将一个进程及其子进程的根目录改变到文件系统中的一个新位置,让这些进程只能访问到该目录。这个功能的想法是为每个进程提供独立的磁盘空间。其后在 1982年,它被加入到了 BSD 系统中。

  2. LXC

    LXC 的意思是 LinuX Containers,它是第一个最完善的 Linux 容器管理器的实现方案,是通过 cgroups 和 Linux namespace 实现的。

    LXC 存在于 liblxc 库中,提供了各种编程语言的 API 实现,包括 Python3、Python2、Lua、Go、Ruby 和 Haskell 等。与其它容器技术不同的是, LXC 可以工作在普通的 Linux 内核上,而不需要增加补丁。现在 LXC project 是由 Canonical 公司赞助并托管的。

  3. Docker

    Docker 是到现在为止最流行和使用广泛的容器管理系统。它最初是一个叫做 dotCloud 的 PaaS 服务公司的内部项目,后来该公司改名为 Docker。Docker 开始阶段使用的也是 LXC ,之后采用自己开发的 libcontainer 替代了它。不像其它的容器平台,Docker 引入了一整个管理容器的生态系统,这包括高效、分层的容器镜像模型、全局和本地的容器注册库、清晰的 REST API、命令行等等。

  4. Linux VServer

    Linux-VServer 也是一个操作系统级虚拟化解决方案。Linux-VServer 对 Linux 内核进行虚拟化,这样多个用户空间环境—又称为 Virtual Private Server(VPS) 就可以单独运行,而不需要互相了解。Linux-VServer 通过修改 Linux 内核实现用户空间的隔离。

    Linux-VServer 也使用了 chroot 来为每个 VPS 隔离 root 目录。虽然 chroot 允许指定新 root 目录,但还是需要其他一些功能(称为 Chroot-Barrier)来限制 VPS 脱离其隔离的 root 目录回到上级目录。给定一个隔离的 root 目录之后,每个 VPS 就可以拥有自己的用户列表和 root 密码。

  5. Virtuozzo/OpenVZ

    Virtuozzo是SWsoft公司(目前SWsoft已经改名为Parallels)的操作系统虚拟化软件的命名,Virtuozzo是商业解决方案,而OpenVZ是以Virtuozzo为基础的开源项目,它们采用的也是操作系统级虚拟化技术。OpenVZ 类似于 Linux-VServer,它通过对 Linux 内核进行补丁来提供虚拟化、隔离、资源管理和状态检查。每个 OpenVZ 容器都有一套隔离的文件系统、用户及用户组等。

三、函数库层虚拟化

操作系统通常会通过应用级的库函数提供给应用程序一组服务,例如文件操作服务、时间操作服务等。这些库函数可以隐藏操作系统内部的一些细节,使得应用程序编程更为简单。

不同的操作系统库函数有着不同的服务接口,例如Linux的服务接口是不同于Windows的。

库函数层上的虚拟化就是通过虚拟化操作系统的应用级库函数的服务接口,使得应用程序不需要修改,就可以在不同的操作系统中无缝运行,从而提高系统间的互操作性。

例如,Wine就是在Linux上模拟了Windows的库函数接口,使得一个Windows应用程序能够在Linux上正常运行。

四、应用程序虚拟化

编程语言层上的虚拟机称为语言级虚拟机,例如JVM(Java Virtual Machine)和微软的CLR(Common Language Runtime)。

这一类虚拟机运行的是进程级的作业,所不同的是这些程序所针对的不是一个硬件上存在的体系结构,而是一个虚拟体系结构。这些程序的代码首先被编译为针对其虚拟体系结构的中间代码,再由虚拟机的运行时支持系统翻译为硬件的机器语言进行执行。


VPS 一键安装纯净 Debian Ubuntu CentOS 那些实现 Docker 的底层 Linux 技术