过去一直在做客户端的开发工作,过程中多少了解和使用过虚拟化技术产品,但对虚拟化技术和实现原理没有一个系统性的认识。这两天抽空学习相关材料,对整体有个印象,这里做一下总结。
虚拟化技术本身很广泛,加上各大公司不同的虚拟化产品越来越受欢迎,在各技术领域影响也越来越大,虚拟化技术就更难界定了。总体来说,任何一种把资源抽象成另外一种形式的技术都是虚拟化技术,包括计算机的虚拟内存、进程,PC上使用的虚拟机软件,Android上的虚拟机,他们用到的技术都是虚拟化技术,只是抽象的粒度不同。
一、分类
为了对虚拟化技术有一个整体上的认识,需要先了解虚拟化技术的分类。不同的人和组织对虚拟化技术的分类不同,维基百科上对于虚拟化技术有两种分类方法,分别是按虚拟对象分类、按抽象程度分类。也有人按计算机系统的分层来分类,感觉这种分类更容易理解一些,这里梳理一下,从计算机系统分层上来看,虚拟化技术可以分成以下几类:
硬件抽象层的虚拟化
通过软件来模拟不同架构的处理器、内存、总线、磁盘IO等硬件设备,被模拟的机器上可以安装不同的系统。运行时,软件会将虚拟机所发出的指令,转换成物理机能够执行的指令,在物理机上执行。这种级别的虚拟化对于模拟相同架构的平台有很好的兼容性,因为相同架构的指令集是相同的,但如果模拟的是不同架构,运行时的开销会比较大。 从历史发展的角度看,虚拟化源于大型机操作系统的分页概念,之后才有论文提出怎样的系统结构是虚拟化系统结构。1979年Unix引入了chroot机制,允许进程和子进程把一个目录指定为根目录,所有的文件系统操作都只能在这个目录内执行,这样就分离了每个进程的访问权限。这样的思路为虚拟化和容器技术奠定了基础,之后开创者们更进一步,各种解决了进程隔离和网络空间隔离的技术都陆续出现。
早期实现的系统虚拟化技术,靠的是纯软件方法。实现复杂且开销大,后来业界逐渐意识到,更好的实现方式必须从体系结构入手。2006年之后Intel和AMD陆续推出了支持硬件虚拟化的CPU,例如Intel的vt技术,AMD的svm技术。之后为了完善虚拟化生态系统,计算机系统的各个层次都开始支持虚拟化,如Intel在芯片组中提供针对IO虚拟化功能的VT-d技术,在网卡中提供支持网络虚拟化的VMDq技术,在云游戏使用的显卡虚拟化技术GVT。
发展到今天,市面上已经有很多优秀的虚拟化应用,这里截取维基百科词条上的一部分
操作系统层的虚拟化
即我们常说的容器化,由操作系统提供支持,运行多个用户态的实例,每个实例有自己的运行环境,拥有自己的文件系统、CPU、内存、磁盘等,但不是一个完整的操作系统,只是一个被隔离的进程。这种技术目前最热门的应用就是Docker,比起虚拟机,Docker资源占用少、体积小、启动快,能够动态伸缩扩容,方便组建微服务架构,在持续集成上常用来提供构建环境。
函数库层面的虚拟化
应用软件最终都是使用系统库函数完成功能的,不同的操作系统有不同的函数接口,函数库的虚拟化就是虚拟操作系统的函数接口,从而实现让软件不需要修改就能运行在原本没有库函数的操作系统上。这一技术的典型应用就是Wine,他能够在linux上运行windows程序。
进程层面的虚拟化
教材上叫编程语言层面的虚拟化,本质上是系统的一个进程,是模拟出来的一台抽象计算机,被设计用来在平台无关的环境中执行程序指令,有处理器、堆栈、寄存器等,但和硬件上的计算机体系结构不同,它是另外一套体系结构。这一类的应用有Java的JVM,Andriod上的Dailvik和ART等。
二、系统虚拟机相关技术概念
虚拟机监控器
硬件抽象层虚拟化使得虚拟机提供了运行整个操作系统所需的功能,虚拟化的具体实现称为虚拟机监控器VMM(Virtual Machine Monitor),也叫Hypervisor,它以软件的形式实现物理机资源。
1974年的一篇文章Formal requirements for virtualizable third generation architectures 将Hypervisor按实现结构分成了两种类型,这个划分方法影响至今.
第一种Hypervisor是直接跑在宿主机上面作为操作系统的,特点是需要硬件支持、程序作为操作系统运行、效率高。客户机操作系统跑在上面对底层资源的访问都会被Hypervisor拦截,由它代为操作并返回结果,从而实现对系统资源的隔离。采用这种类型的虚拟机软件有VMware ESXi、 Xen等。
第二种Hypervisor是作为应用程序跑在操作系统上的,客户端机操作系统跑在他上面所有访问也会被拦截,由于Hypervisor不直接访问硬件资源,因此运行效率通常比第一种低。采用这种类型的虚拟机软件有VMware Workstation、VirtualBox等。
以下是维基百科上的分类,第一种是”原生虚拟化“、第二种是”需要宿主操作系统“的虚拟化
KVM
从前面的分类列表里可以看到KVM属于原生虚拟化程序,起初是单独的程序,后来被合并到Linux内核2.6.20中,使得Linux在内核层面支持虚拟机,让每一个虚拟机实例能够作为不同的Linux进程运行。
KVM需要CPU支持虚拟化,例如Intel的VT和AMD-V,它以可加载内核模块的形式存在,并且只负责CPU和内存的虚拟化,其他设备如IO虚拟化需要用户空间负责。例如截图中提到的QEMU,早期是纯软件实现的虚拟机,模拟了CPU、内存、IO、网卡、声卡等全部的硬件设备,等到KVM开发时直接在QEMU的基础上进行开发,把CPU和内存的虚拟化放到了KVM中实现,而IO等模块的虚拟化依然放在了QEMU。
以上内容和图表分别参考和引用自以下材料:
虚拟化技术
Docker入门教程
虚拟机
Java虚拟机
Linux云计算底层技术之 KVM 初探
《系统虚拟化: 原理与实现》
Intel虚拟化技术
Linux虚拟化KVM-QMUE分析