一 虚拟化的定义
虚拟化是云计算的基础技术之一。广义的虚拟化是将任何一种形式的资源抽象成另一种形式的技术,包括系统虚拟化、网络虚拟化、微处理器虚拟化、文件虚拟化、存储虚拟化等等。其主要目的为了摆脱物理限制的约束,将多个资源抽象成一份,或者同时将一个资源抽象成多分,比如操作系统的虚拟地址空间就是对物理内存的虚拟化。虚拟化的主要功能有:系统资源管理、容错、软硬件维护、增强系统安全、提升性能、节能并降低系统运行成本。云计算的一个核心思想就是在服务端提供集中的计算资源,同时这些计算资源要独立地服务不同的用户,也就是在共享的同时,为每个用户提供隔离、安全、可信的工作环境。
抽象的意义在于上层只需要知道下层抽象的接口,而不需要了解下层的内部运作机制,上图是典型计算机系统的各个抽象层。硬件抽象层是软件所能控制的硬件的抽象接口,包括CPU的寄存器、内存管理模块、IO端口和内存映射的IO地址等。API抽象层的对象是一个进程所能控制的系统功能的集合,例如创建进程、内存申请与归还、进程间同步与共享、文件系统和网络操作等。系统虚拟化可以体现在不同的抽象层次上:
1,硬件抽象层上的虚拟化为Guest OS提供与物理硬件相同或相近的硬件抽象层,这通常要求虚拟系统和真实的系统的ISA(Instruction Set Architecture)是相同的。虚拟系统的大部分指令可以在Host 上直接运行,只有需要虚拟化的指令才由虚拟化软件进行处理,从而降低虚拟化的开销。其他部分如中断控制器、设备等可以不同。 VMware和Xen属于这一层的虚拟系统。
2,操作系统层上的虚拟化主要由操作系统内核提供多个互相隔离的用户态实例(也叫容器),每个实例对用户来说就像一台真实的计算机,有独立的文件系统、网络、系统设置和库函数。因 为是内核主动提供的虚拟化,所以效率很高,不需要硬件支持,但缺点是容器中的OS和Host OS必须是同一种OS,并且隔离粒度较粗。Paralles的Virtuozzo,Solaris的Zone,Linux的VServer ,User Mode Linux 都属于这一类型。
3,库函数层上的虚拟化是通过虚拟化操作系统的API,使应用程序不需要修改就可以在不同的OS中运行,从而提高系统间的互操作性。比如Wine系统可以在linux上模拟Windows,而Cygwin在Windows 上模拟Linux。
4,编程语言层的虚拟化即语言级虚拟机,比如JVM,CLR,Erlang VM等。这一类虚拟机运行的是进程级的作业,抽象不是针对一个硬件体系结构,而是一个虚拟体系结构。程序代码由虚拟机 的运行时系统先翻译为硬件的机器语言再执行。因为虚拟机作为一个进程运行在Host OS上,所以他们都属于进程级虚拟化。
系统虚拟化是虚拟化技术中的一种,抽象的粒度是整个计算机。早期的虚拟机在性能上有很大的损失,但最近由于硬件虚拟化技术的支持,如Intel VT,AMD SVM,虚拟机的性能大大提高。虚拟机是由系统虚拟化抽象出的计算机环境,包括CPU、内存、IO。每个虚拟机都有自己的虚拟硬件环境,可以运行不同的Guest OS,因此在 一台计算机上可以虚拟出多个虚拟机。本质上虚拟机和物理计算机可以是不同的ISA,但是大量指令的虚拟会导致性能大大下降。狭义的虚拟机定义是:对物理机进行一种高效隔离的复制,它的特点是同质、高效、资源受控。系统虚拟化的好处主要由以下几种:
封装性:虚拟机快照,克隆,挂起,灾难恢复,便与调试
多实例:优化资源调度,节能并降低系统管理成本
隔离性:故障隔离
硬件无关性:负载均衡、虚拟机迁移
特权功能:VMM提供的功能,时间记录与与回放,入侵检测等
二 可虚拟化系统
特权指令是指具有特殊权限的指令。这类指令只用于操作系统或其他系统软件,一般不直接提供给用户使用。 在多用户、多任务的计算机系统中特权指令必不可少。它主要用于系统资源的分配和管理,包括改变系统工作方式,检测用户的访问权限,修改虚拟存储器管理的段表、页表,完成任务的创建和切换等。常见的特权指令主要有以下几种:
1,有关对I/O设备使用的指令 如启动I/O设备指令、测试I/O设备工作状态和控制I/O设备动作的指令等。
2,有关访问程序状态的指令 如对程序状态字(PSW)的指令等。
3,存取特殊寄存器指令 如存取中断寄存器、时钟寄存器等指令。
特权级(privilege level)是一种机制来保护数据和阻止恶意行为,是电脑操作系统提供不同权限访问级别的资源。特权级分为0~3共4级,在Windows中只使用特权级0和特权级3,特权最高的一般是特权级0,可以直接操作硬件,如CPU和内存,一般操作系统和驱动运行在此级别下。特权级3是给一般的程序使用的,可以调用基本的CPU指令。在特权级3无法调用特权级0的指令,如果调用则显示为非法指令。系统一般有3种主要的资源受到保护:内存,I/O端口以及执行特殊机器指令。特权级也被称为保护环(protection ring),在诸多机器指令中,只有大约15条指 令被CPU限制只能在ring 0执行,这些指令如果被用户模式的程序所使用,就会颠覆保护机制或引起混乱。如果企图在ring 0以外运行这些指令,就会导致一个一般保护错(general-protection exception),就像一个程序使用了非法的内存地址一样。类似的,对内存和I/O端口的访问也受特权级的限制。Linux的请求特权级包含在段选择符中。
敏感指令是虚拟系统中的一种特殊指令,主要包括:
1,企图访问或修改虚拟机模式或机器状态的指令。
2,企图访问或修改敏感寄存器或存储单元,如时钟寄存器、中断寄存器等的指令。
3,企图访问存储保护系统或内存、地址分配系统的指令4,所有I/O指令。
所有的特权指令都是敏感指令,但并非所有的敏感指令都是特权指令。如果所有敏感指令都是特权指令,那么是一个可虚拟化的结构,否则,它无法支持在所有敏感指令上触发异常,因此不 是一个可虚拟化的结构,这就是所谓的“虚拟化漏洞”。
如果一个系统是可虚拟化结构,则将VMM运行在系统的最高特权级上,而guestOS运行在非特权级上,当guestOs要执行敏感指令(此时也就是特权指令)而陷入到VMM时,VMM模拟执行执行引起 一场的敏感指令,这种方式叫“陷入再模拟”。敏感指令引入虚拟化后,Guest OS就不能运行在Ring 0上。因此,原本需要在最高级别下执行的指令就不能够直接执行,而是交由VMM处理执行。这部分指令称为敏感指令 。当执行这些指令时,理论上都要产生trap被VMM捕获执行。
如果处理器不可虚拟化,可以采用三种不同的方式弥补这种缺陷:基于软件的完全虚拟化、硬件辅助虚拟化、类虚拟化。不管什么虚拟化方式,其VMM对物理资源的虚拟可以归结为三个主要任务:处理器虚拟化、内存虚拟化和IO虚拟化。处理器虚拟化包括虚拟寄存器、虚拟上下文和虚拟处理器。敏感指令MOV CR0,EAX的执行步骤如下:
1,CPU 取指令,发现特权级别不符合,抛出异常
2,VMM截获这个异常,模拟处理器的行为,
3,读取EAx的内容存到虚拟的CR0中
4,当虚拟机需要读CR0时,处理器抛出异常,有VMM从虚拟CR0中而不是物理CR0中读取内容返回给虚拟机
CR0就是虚拟寄存器,本质上就是一小块内存。虚拟处理器需要具备与物理处理器的一致功能和行为:
1,指令集合与执行效果2,寄存器集合3,特权模式集合4地址翻译系统5保护机制6中断异常机制
VMM的陷入是利用了处理器的保护机制,即中断和异常:
1,基于处理器的保护机制出发的异常
2,虚拟机主动触发异常,即通常所说的陷阱
3,异步中断,包括处理器内部的中断源和外部设备的中断源
VMM管理物理处理器,负责在虚拟处理器上管理进程的调度和切换。Guest OS中进程的切换也需要保留现场,这个现场就是上下文。
进程上下文主要就是雨运算相关的寄存器状态,如EIP,ESP等。切换时将寄存器里面的值保存在内存中,而另一个进程的上下文被回复到相应的寄存器中继续执行。虚拟处理器上敏感指令涉及的寄存器都需要保存到上下文中,所以虚拟处理器上下文比进程上下文更加复杂。