(ZZ) 剖析系统虚拟化(4)——VMware ESX架构介绍

上篇文章已经向大家介绍了VMware vSphere,而本篇将继续把重点放在vSphere身上,并向介绍大家vSphere之核心ESX的架构,虽然关于ESX架构的公开资料较少,但是基于这些已公开的资料,并加上我的一些实际经验,我觉得还是能对ESX的架构有一个大致的描述,下图为ESX的架构:

ESX Server Architecture

图1. ESX的架构图(点击可看大图)(参【2】)

ESX主要可被分为两部分:其一是用于提供管理服务的Service Console,其二是ESX的核心,也是主要提供虚拟化能力的VMKernel。

Service Console

简单的来说,Service Console就是一个简化版Redhat Enterprise OS。虽然其不能实现任何虚拟化功能,但是对这个ESX架构而言,它却是一个不可分割的一部分。主要有五个方面功能:

  1. 启动VMKernel,当ESX主机启动的时候,首先会启动Service Console,接着在Linux runlevel 3上启动VMKernel,之后将全部硬件资源的管理权移交给VMKernel。当VMKernel启动成功之后Service Console就成为运行VMKernel上面的第一个虚拟机。
  2. 提供各种服务接口,比如命令行,Web接口,SDK接口等,并安装VirtualCenter Agent以支持很多需要和Virtual Center配合的高级服务,比如,vMotion和DRS等。
  3. 性能检测,因为所有VMkernel的性能数据都会记录在Service Console的/proc目录下,所以不仅能够通过脚本来处理这些性能数据,而且还能使用Service Console自带的ESXTOP命令来观测。
  4. 认证,Service Console提供多种认证机制。
  5. 负责主机部分硬件的管理,比如,鼠标,键盘,显示屏和CD-ROM等等。

注:虽然Service Console提供了许多功能,但因为其本身资源所限的原因(关于这点,我曾经和一位VMware工程师有过聊天,好像整个Service Console大概只能占有280MB内存和少量的I/O),所以不适合在Service Console中执行一些重量级的任务,比如:上传或者复制虚拟磁盘(Virtual Disk)。

VMKernel

VMKernel是由VMware开发的基于POSIX协议的操作系统,它提供了很多在其它操作系统中也能找到的功能,比如,创建和管理进程,信号(Signal),文件系统和多线程等。但它是为运行多个虚拟机而“度身定做”的。它的核心功能是资源进行虚拟化。下面将通过CPU,内存和I/O这三个方面,来讲解VMKernel是如何实现虚拟化的。

CPU

在CPU方面,ESX使用了在第二篇提到的两个全虚拟化技术:优先级压缩(Ring Compression)和二进制代码翻译(Binary Translation)。

优先级压缩,指的是为了让VMKernel获得所有物理资源的控制权,比如CPU。这就需要让VMKernel运行在Ring 0,在其上面的虚拟机内核代码是运行在Ring 1,而虚拟机的用户代码只能运行在Ring 3上。这种做法不仅能让VMKernel安全地控制所有的物理资源,而且能让VMKernel截获部分在虚拟机上执行的特权指令,并对其进行虚拟化。

二进制代码翻译,虽然上面的优先级压缩这个技术已经处理了很多特权指令引发的异常情况,但是由于X86架构在初始设计方面并没有考虑到虚拟化这个需求,所以有很多X86特权指令成了优先级压缩的漏网之鱼,虽然通过传统的Trap-Emulation技术也能处理这些指令,但是由于其不仅需要花时间观测有潜在影响的指令,而且还要监视那些非常普通的指令,导致Trap-Emulation的效率非常低,所以VMware引进了二进制代码翻译这个技术,这个技术能让那些非常普通的指令直接执行,不干涉,并提供接近物理机的速度,但会扫描并修改那些有嫌疑的代码,使其无法对虚拟机造成错误的影响。由于大多数代码都不属于有嫌疑的,所以二进制代码翻译的效率远胜Trap-Emulation。还有经过VMware长达十年的调优,使得二进制代码翻译这个技术越发优秀。

接下来,谈一下的VMware的二进制代码翻译技术的特点:

  1. 纯二进制:二进制翻译器的输入和输出都是二进制的X86代码,而不是文本形式的源代码。
  2. 动态:二进制代码只会在运行时翻译,翻译器会在生成代码之间进行串联。
  3. 随需应变:只有在代码即将执行时翻译,这样只有代码才会被翻译,从而避免对数据的进行翻译。
  4. 基于底层:翻译器只会根据X86指令集进行翻译,而不是上层的二进制接口。
  5. 子集:如果翻译器的输入是完整的X86指令集,但是它的生成的代码是X86的安全子集,同时意味着生成的代码能在低权限的用户模式运行。
  6. 灵活:翻译的代码会根据虚拟机的运行状态来进行调整,从而提升效率。

对于CPU虚拟化而言,只有上面这两种技术是远远不够的,还需要调度技术,也就是需要CPU调度器(Scheduler)。但是CPU的调度器和常见操作系统的调度器是很不同的,因为CPU的调度器的责任是将执行上下文分配给一个处理器,而普通操作系统的调度器则是执行上下文分配给一个进程。同样的是,CPU调度器并没有采用传统的优先级机制,而是采用平衡共享的机制,来将处理器资源更好地分配给虚拟机,同时也能设定每个虚拟机的份额,预留和极限等设定值。在VMware最常用的CPU调度器算法,是“Co-Scheduling”算法,其也常被称为“gang-scheduling”算法,它的核心概念是让相关的多个进程尽可能在多个处理器上同时执行,因为当多个相关进程同时执行时,它们互相之间会进行同步,假设他们不再一起执行的话,将会增加很多由同步导致的延迟。在vSphere中,VMware推出了Co-Scheduling的更新版本,叫做Relaxed Co-Scheduling,它能更好地与虚拟机进行协作。同时,为了更好利用最新推出了多核系统,VMware也给调度器添加很多新的特性,主要集中在两方面:其一是对现有多核环境的探知,比如对NUMA(Non-Uniform Memory Access),Hyperthreading,VM-Affinity的支持。其二是在多核之间进行有效的负载均衡。

 

内存

VMKernel在内存虚拟化方面所采用的核心机制就是“影子页表 (Shadow Page Table)”。在探讨影子页表的机制之前,先看一下传统页表的运行机制,其实也很简单,就是页表将VPN(Virtual Page Number 虚拟内存页号)翻译成MPN(Machinel Page Number,机器内存页号),之后将这个MPN发给上层,让其调用。但是这种做法在虚拟的环境是不适用的,因为当虚拟机从页表得到的翻译之后的页号不是MPN是PPN(物理内存页号),之后需要从PPN再转换成MPN,由于这样将经历两层转换,所以肯定会较高的成本,所以VMware引入影子页表这个机制,它维护为每个Guest都维护一个“影子页表”,在这个表中能直接维护VPN和MPN之间映射关系,并加载在TLB中。所以通过“影子页表”这个机制能够让Guest在大多数情况下能通过TLB直接访问内存,保证了效率。

Shadow Page Table

图2. 内存虚拟化(点击可看大图)

由于虚拟机对内存的消耗胜于对CPU的消耗,同时介于内存的内容同质化和浪费这两个现象在虚拟环境非常普遍,所以VMware在影子页表的基础上引入了三个非常不错的技术来减少内存的消耗,以支撑更多的虚拟机:其一是Memory Overcommit机制,这个机制通过让虚拟机占用的内存总量超越物理机的实际容量来使一台物理机能支持更多的虚拟机。其二是用于减少虚拟机之间相似内存页的Page Sharing,它主要实现是通过对多个虚拟机的内存页面进行Hash,来获知那些内存页面是重复的,接着将多个重复的内存页面整合为一个replica,之后通过CoW(Copy On Write)的机制来应对对内存页面的修改。其三是能在各个虚拟机之间动态调整内存的Balloon Driver,其实现机制就是通过给每个虚拟机安装VMware Tools(可以把VMware Tools看作VMware的驱动)来装入Balloon Agent,在运行的时候,Balloon Agent会和主机的Balloon Driver进行沟通,来调整每台虚拟机的内存空间,来将那些在某些虚拟机上不处于工作状态的内存通过swapping等方式来闲置出来,以拨给那些急需内存的虚拟机。

 

I/O

VMKernel的做法是通过模拟I/O设备(磁盘和网卡等)来实现虚拟化。而且主要选取最大众化的硬件来模拟,比如440BX的主板,LSI Logic的SCSI卡和AMD Lance的网卡,从而提高这些模拟I/O设备的兼容性。 对Guest OS而言,它所能看到就是一组统一的I/O设备,同时Guest OS每次I/O操作都会陷入到VMM,让VMM来执行。这种方式,对Guest而言,是一种非常透明的方式,因为无需顾忌其是否和底层硬件兼容,比如Guest操作的是SCSI的设备,但实际物理机可以SATA的硬盘。虽然这种模拟I/O设备的做法有一定开支,但在经过了VMware长时间优化,使得其在处理小规模的I/O时,非常游刃有余,但是在这个模型的方法在处理大规模I/O的时候,有时候可能会出现力不从心的局面,所以VMware在I/O层推出一些半虚拟机技术,比如,vmxnet半虚拟化网卡。

其次,为了更好地为VM服务,VMKernel还支持一些高级I/O技术:

  1. VMFS,是VMware为虚拟化设计的分布式文件系统,它不仅能给虚拟机提供高速的I/O,而且由于它自带的锁机制,所以允许多个主机能同时访问同一个文件系统。因为放置在其上面的多为大于1G的Virtual Disk,为了减少存取文件系统数据结构的元数据的大小,它Block大小被设计为1MB到256MB,默认是1MB,使得其元数据得到了精简,而且所有的元数据都被放置在内存中作为缓存,以提高速度。
  2. Virtual Switch,其也是VMKernel的一个组件,主要给ESX主机上面所有虚拟机提供网络支持。在功能方面。除了不支持STP(Spanning ree protocol,生成树协议)和无需通过检测网络流量来获得之外,其他基本和物理交换机类似。 在vSphere中,VMware也推出了Virtual Switch的升级版本Distributed Virtual Switch,它将解决一些Virtual Switch的瑕疵。
  3. 支持新的物理层技术:VMDirectPath能增强网络和存储方面的I/O性能,PCI-SIG的SR-IOV硬件虚拟化技术能更好地对PCIe设备进行虚拟化, vStorage的 Thin Provisioning和Linked Clone这两个技术可减少存储空间达50%左右。
  4. 网络和存储方面的调度:除了系统能通过预设定一些网络和存储的参数来提升性能,用户还可以通过GUI(比如vSphere Client)来对网络和存储这两方面进行调优。

 

总结

在开头也说,有可能是竞争的原因,使得VMware已经越来越少地公开它的技术资料,特别是最核心的ESX技术。 所以上面这些材料主要是来自于ESX 2的文档,而不是来自于最新的vSphere 4的文档,但是从这些文档中,我们还可以可以看出它绝对是全虚拟化的巅峰,并且在其新版中也已经引入了代号为VMI的半虚拟技术和支持Intel/AMD最新的硬件辅助虚拟化技术。就像本系列第二篇X86虚拟化技术所讲的那样,虽然在速度上面,半虚拟化技术和硬件辅助虚拟化技术的确各有千秋,但是他们都有软肋,半虚拟化技术是需要对Guest OS进行修改,硬件辅助虚拟化技术则是不够成熟,而且ESX的全虚拟化技术是经过VMware高级工程师们长达10年优化的,所以在跑某些Workload的时候,全虚拟化反而速度更优。综上所述,用户在使用最新版ESX的时候,应该根据不同的workload来选择不同的虚拟化方法,具体可以查看VMware的白皮书(见参3)。

 

 

参考资料:

  1. 《VMware ESX Server Advanced Technical Design Guide》。
  2. VMWare ESX Server 2 – Architecture and Performance Implications
  3. Virtual Machine Monitor Execution Modes in VMware vSphere 4.0
  4. Architecture of VMware ESXi。
  5. VMware vSphere 4: The CPU Scheduler in VMware ESX 4。
  6. Understanding Memory Resource Management in VMware ESX Server。
posted @ 2013-11-29 17:01  水芊芊  阅读(2558)  评论(0编辑  收藏  举报