虚拟化技术

从记录知识到理解知识再到运用知识再到创造知识中徐徐前进。关于云计算里面的虚拟化技术,深感较为复杂,需要花功夫去理解。在这里,我先给自己开个坑,浅显且不系统地记录相关基础知识,待之后再好好学习并整理。

虚拟化技术

虚拟化,通俗的理解是:通过一定的技术手段对传统的硬件、软件、固件等进行模拟,为上层提供服务,“欺骗”上层以达到“让上层认为自己运行在真实的环境下”的目的。
其实多用户多进程的操作系统也可以理解为一种虚拟化。操作系统通过时间片等机制达到“欺骗”应用程序的目的,让应用程序以为自己独占一个计算机。
可以这么说,虚拟化的本质是对某种资源的一种抽象。
最简单的模拟实现方式是解释执行:取一条指令模拟出这条指令执行的结果,再继续取下一条指令,从某种程度上解决了陷入再模拟,也避免了虚拟化漏洞。在解释执行方式中,编译好的二进制代码是不会被载入物理CPU直接运行的,而是由解释器逐条解码,再调入对应的函数来模拟对应指令的功能,而这一最大的缺点是性能太差。

基础知识

特权指令与非特权指令

特权指令指具有特殊权限的指令。这类指令只用于操作系统或其他系统软件,一般不直接提供给用户使用。
特权指令只能由操作系统使用,由于这类指令的权限最大,如果使用不当,将导致整个系统崩溃。比如:清内存、置时钟、分配系统资源、修改虚存的段表和页表,修改用户的访问权限等。为了保证系统安全,这类指令只能用于操作系统或其他系统软件,不直接提供给用户使用。为了防止用户程序中使用特权指令,用户态下只能使用非特权指令,核心态下可以使用全部指令。当在用户态下使用特权指令时,将产生中断以阻止用户使用特权指令。所以把用户程序放在用户态下运行,而操作系统中必须使用 特权指令的那部分程序在核心态下运行,保证了计算机系统的安全可靠。从用户态转换为核心态的唯一途径是中断或异常。

敏感指令

敏感指令是指操作特权资源的指令。包括修改虚拟机的运行模式或者下面物理机的状态。

敏感非特权指令

Xen虚拟机系统所采用的半虚拟化技术通过软件方法实现了x86架构的虚拟化,解决了x86架构所固有的虚拟化缺陷,即敏感和特权指令无法被VMM所捕获的缺陷。
G.Popek和R.Goldberg在1974年发表的论文中提到,作为向上层VM提供底层硬件抽象的一层轻量级的软件,VMM必须满足以下3个条件:
1.等价性(Equivalence) :应用程序在VMM 上的虚拟机执行,应与物理硬件上的执行行为相同。
2.资源控制(Resource Control) :物理硬件由VMM全权控,VM 及VM上的应用程序不得直接访问硬件。
3.有效性(Efficiency) :在虚拟执行环境中应用程序的绝大多数指令能够在VMM不干预的情况下,直接在物理硬件上执行。
CPU的指令按照运行级别的不同,可以划分为两类:
1.特权指令 :只能在最高级别上运行,在低级别状态下执行会产生trap。例如:LIDT只能在系统模式下执行,在其他模式下都会产生trap,中止执行。
2.非特权指令 :可以在各个级别的状态下执行。
引入虚拟化后,Guest OS就不能运行在Ring 0上。因此,原本需要在最高级别下执行的指令就不能够直接执行,而是交由VMM处理执行。这部分指令称为敏感指令 。当执行这些指令时,理论上都要产生trap被VMM捕获执行。敏感指令:Guest OS中必须由VMM处理的指令,因为这些指令必须工作在0环。
敏感指令包括:
1.企图访问或修改虚拟机模式或机器状态的指令。
2.企图访问或修改敏感寄存器或存储单元,如时钟寄存器、中断寄存器等的指令。
3.企图访问存储保护系统或内存、地址分配系统的指令。
4.所有I/O指令。
根据Popek和Goldberg的理论,如果指令集支持虚拟化就必须满足所有的敏感指令都是特权指令 。这样,当Guest OS运行在非最高特权级时,执行任意特权指令都能产生trap。该条件保证了任何影响VMM或VM正确运行的指令在VM上执行时都能被VMM捕获并将控制权转移到VMM上,从而保证了虚拟机环境的等价性和资源可控制性,保证虚拟机正确运行。但是,x86架构并不满足这个条件。由于有些敏感指令不属于特权指令,从而阻碍了指令的虚拟化。(x86不满足的原因:有些必须由VMM处理的0环指令,工作在1环也不会产生trap,即敏感指令包含非特权指令。但是为了保证VMM对资源的控制,敏感指令必须工作在0环,所以这些非特权指令也必须陷入。)x86结构上的这些不是特权指令的敏感指令,称为临界指令 (Critical Instructions)。这些临界指令在x86架构下有17个,主要包含敏感指令的两类:敏感寄存器指令和保护系统指令(上面的2,3类)。
x86体系中含有17个敏感非特权指令,称为关键指令。敏感性意味着VMM不可以轻易让Guest OS执行这些指令;非特权意味着这些指令可以执行在ring3上。这种指令是无法自动陷入的,为了让VMM控制资源,需要通过人为在这些指令处做陷入处理,即通过二进制翻译、Hypercall等方式强迫陷入并模拟。

经典的虚拟化方法

特权解除

为了方便VMM管理系统资源并向虚拟机提供服务,将Guest OS的内核特权级由ring 0变为ring 1。
带来的问题:特权环ring的偏移,环压缩等

陷入模拟

后面有介绍

使CPU进入系统态的三种方式

中断:来自于外部设备的中断请求。当有中断请求到来时,CPU自动进入系统态,并从某个预定地址开始执行指令。中断只发生在两条指令之间,不影响正在执行的指令。
异常:无论是在用户空间或系统空间,执行指令失败时都会引起异常,CPU会因此进入系统态(如果原先不在系统空间),从而在系统空间中对异常做出处理。异常发生在执行一条指令的过程中,所以当前执行的指令已经半途而废了。
自动陷入:以上两种都CPU被动进入系统态。而自陷是CPU通过自陷指令主动进入系统态。多数CPU都有自陷指令,系统调用函数一般都是靠自陷指令实现的。一条自陷指令的作用相当于一次子程序调用,子程序存在于系统空间。

参考资料

特权指令
特权指令与非特权指令
敏感指令
关于特权解除和陷入模拟的理解
KVM虚拟化技术之Hypervisor的实现

系统虚拟化

完全虚拟化与准(半)虚拟化

完全虚拟化,简单的理解是:用软件完全模拟硬件;准虚拟化,也叫半虚拟化或类虚拟化,简单的理解是:如果不能完全模拟硬件,则对要运行在硬件环境下的软件(如操作系统)的源代码进行相应的修改。

完全虚拟化

模拟相同指令体系结构的物理机对应的虚拟机,有很多非敏感指令不需要模拟而可以直接运行在物理CPU上,对于敏感指令,则可以替换为跳转指令或者陷入到VMM(Hypervisor)中去的指令,使物理CPU一旦运行到敏感指令,控制流就会进入VMM,由VMM代为模拟执行,这就是所谓的扫描与修补技术。扫描与修补技术直接在虚拟机内存中进行代码修补,其须维护一份与补丁对应的原始代码的备份,以便在需要时将代码恢复原状。
二进制代码翻译技术:代码基本块,跟编译技术里面的概念类似。先将代码划分为若干个代码基本块(QEMU将代码基本块存于VMM中的代码缓存里面)进行翻译。一些虚拟执行的计算密集型程序会出现性能好于源代码执行,其原因就是指令、数据缓存有更好的局部性。

硬件辅助虚拟化

把纯软件虚拟化技术的功能,部分或者全部用硬件实现,提高虚拟化的性能。
CPU:Intel VT、AMD SVM

  • 提供新的特权层,比如加入ring -1,专门运行VMM
  • 优化指令集,减少二进制转换的需求
  • 为内存映射提供专门的加速电路
    网卡、显卡等加速器支持:
  • 提供多组共享单元,支持多虚拟机上下文切换。
动态指令转换虚拟化

暂时空缺

准(半)虚拟化

上面有所介绍

硬件虚拟化

硬件虚拟化主要涉及CPU虚拟化、内存虚拟化和I/O虚拟化。

CPU虚拟化

上面有所介绍。

虚拟CPU的调度

常见算法:
BVT、sEDF、Credit based调度。

内存虚拟化

现代操作系统的基本内存管理为段页式内存管理。
虚拟化下的内存管理:

  • HPA(Host Physical Address): 机器地址,或宿主机器物理地址。
  • GPA(Guest Physical Address):物理地址,经过VMM抽象供虚拟机看到的假物理地址。
  • GVA(Guest Virtual Address):GuestOS给应用程序提供的地址空间。
    内存虚拟化的核心是从GVA到HPA的映射。
影子页表(SPT,Shadow Page Table)

客户页表加载到客户虚拟机的虚拟内存管理单元,影子页表加载到物理内存管理单元,由CPU使用。
同步SPT和GPT(Guest Page Table)的两种方法:
Lazy法:当Guest OS修改客户页表时,不进行模拟。
Eager法:VMM监视客户页表,当Guest OS试图修改客户页表时,引发#PF(Page Fault)。
SPT与GPT的同步开销比较大。

嵌套页表:本质上是从GVA到HPA的多级映射。

I/O虚拟化

三种设备虚拟化的方式:
模拟、虚拟分离驱动、直通。
硬件支持的DMA重定向:所谓的重定向就是对目标地址进行转换和更改,DMA重定向硬件利用分层页表结构对地址进行转化。DMA重定向硬件将DMA地址(这里的DMA地址本质上是虚拟机中的GPA)最终转化为HPA(Host Physical Address)以实现最终主机物理地址的访问。
不同虚拟机之间的隔离是通过防止分配到其他虚拟机的资源(CPU、I/O设备)访问到本虚拟机的物理地址。每个虚拟机都会有自己独立的物理地址空间,即GPA(Guest Physical Address)空间,该空间不同于主机物理地址空间,即HPA(Host Physical Address)空间。DMA重定向硬件将从I/O设备发过来的访问请求中包含的地址看做是DMA地址,根据不同的使用配置,该DMA地址可能是GPA

参考资料

系统虚拟化——原理与实现
CPU的半虚拟化技术
影子页表原理
DMA重定向

网络虚拟化

交换机(网桥)的局限在于,随着网络规模不断扩大,网络不便于管理、通信性能下降,并且无法阻止广播。

虚拟网卡

软件模拟硬件

无需root权限、共享性好、性能差、不支持ICMP、Guest不能被外网访问。

半虚拟化网卡

性能好、可共享物理硬件、Guest内部需要专用驱动。

直通

直接将物理网卡分配给Guest、开小小、性能好、共享性差、Guest中直接安装网卡驱动、需要IOMMU支持。

二层虚拟化

同一物理机内:软件网桥
跨宿主机:如分布式以太网

  • 基于物理交换机:可管理性差、不能跨越网络
  • OpenVPN:可管理、性能差(Server瓶颈)

三层虚拟化

虚拟路由器:性能较差,容易出现三角路由问题
分布式虚拟路由:解决以上问题

什么是软件定义网络

??????

为什么要软件定义网络

统一网络管理和迁移性的需求以及创新的需求。

虚拟网络互连与隔离控制方案

流表代替传统路由表、基于源端-目的端的流表匹配。
虚拟机接入网络时,只需要根据自身的配置信息即可完成流表规则,以进入转出组合形式完成虚拟网络互连。
通过多级流表和表内多优先级结构达到隔离虚拟网络租户的目的。

虚拟化的其他内容

虚拟化的用途

工作负载隔离、工作负载合并、工作负载迁移、工作负载嵌入。
服务器的合并、测试与开发、快速部署。
负载均衡、灾难恢复。

弹性内存:Ballon机制

VMM能够控制和监控ballooning,所以ballooning能够潜在节约大量内存,不同于内存页共享技术(KSM是内核自发完成的、不可控),VM系统的内存只有在通过命令行调整balloon时才会随之改变,所以能够监控系统内存并验证ballooning引起的变化。

虚拟机迁移

数据中心:无需停机、不影响上层应用、需要共享磁盘、对带宽要求较高。
在线迁移

虚拟机快照

虚拟机失效后通过快照能够恢复虚拟机运行。

虚拟磁盘优化

虚拟电器

虚拟化安全

参考资料

KVM之四:内存balloon的奇妙

轻量级虚拟化

容器是APP层面的隔离,虚拟化是物理资源层面的隔离。
容器在运行时实质是运行在独立命名空间的进程,容器状态随容器删除而丢失。
Linux docker是Linux的特殊进程namespace,所以不能在Linux docker里使用win应用。