- 云原生架构:从技术演进到最佳实践
- 贺阮 史冰迪
- 3045字
- 2022-05-06 13:29:39
2.5 常见的虚拟化产品
虚拟化技术发展几十载,已经有了一些虚拟化产品,如VMware、Xen、KVM等,下面进行具体介绍。
2.5.1 VMware
虚拟化最早产生于大型机中,通过对大型机进行分区来提高硬件资源的利用率。后来随着x86 架构的风靡,以及硬件成本的不断降低,虚拟化经历了一段时间的低潮期。但随着时间的推移,软件越来越复杂,对应的IT基础架构越来越庞大,使得服务器数量越来越多,与此对应的耗电和制冷等成本也节节攀升。1999 年,为了解决上述难题,VMware 推出了 VMware Workstation,通过软件辅助全虚拟化技术,在一个操作系统内虚拟出多台虚拟机。
2.5.2 Xen
在VMware推出VMware Workstation后没多久,开源社区在虚拟化领域也有了突破。2003年剑桥大学推出了Xen Hypervisor,它为Linux提供了类虚拟化的内核。再加上与QEMU模拟器软件的搭配,形成了完善的虚拟化解决方案。
目前最新版本的Xen支持类虚拟化和硬件辅助虚拟化。它在不支持VT-x技术的CPU上也能使用,但是只能以类虚拟化模式运行。在Xen中,虚拟机监视器运行在Ring 0下,GuestOS运行在Ring 1下,应用程序运行在Ring 3下。系统引导时,Xen被引导到Ring 0的内存中,在Ring 1下启动修改过的内核,这被称作Domain0。接下来可以创建更多的Domain虚拟机,也可以进行销毁和迁移等操作,如图2-12所示。
图 2-12
2.5.3 KVM
KVM(Kernel-based Virtual Machine)是一种硬件辅助虚拟化技术,由以色列的Qumranet公司开发,该公司后来被 RedHat 收购。2007 年KVM 被合并到Linux 内核 2.6.20,目前它是Linux的一个内核模块。借助KVM模块,可以将Linux内核转化为虚拟机监视器。当然,KVM需要CPU有相关的虚拟化支持。KVM机制示意图如图2-13所示。
KVM包含一个内核模块kvm.ko,以及与架构相关的kvm-intel.ko或kvm-amd.ko。KVM对外暴露/dev/kvm接口,客户模式的QEMU利用它通过ioctl系统调用(一个专门用于设备输入/输出操作的系统调用)进入内核模式。在创建虚拟CPU后,通过VMLAUCH指令进入客户模式,进而执行虚拟机中的指令。如果虚拟机发生外部中断之类的情况,则会导致虚拟机退出至宿主机中进行异常处理,处理完成后可以通过VMRESUME指令重新进入客户模式,执行客户代码。周而复始,虚拟机指令不断执行,形成虚拟机和物理机分时复用CPU的状态。
图 2-13
使用KVM创建的虚拟机实际上就是一个传统的Linux进程,它运行在QEMU-KVM进程的地址空间。如果在虚拟机的no-root模式下执行非敏感指令,则可以直接在物理CPU上执行。当虚拟机在no-root模式下执行敏感指令时,则会触发VMExit,CPU会从no-root模式切换到root 模式。KVM Hypervisor 会接管对敏感指令进行一系列处理,处理完成后会触发 VMEntry进入虚拟机的GuestOS继续执行其他指令。
2.5.4 QEMU
QEMU是开源的软件辅助全虚拟化解决方案,其主要包含两部分内容:指令模拟器和虚拟机监视器。
指令模拟器通过二进制代码翻译的方式为虚拟机提供指令支持,可以支持跨系统架构的转义,比如将x86架构的指令转义为ARM架构的指令,从而使得在x86架构上可以运行ARM架构的虚拟机。
虚拟机监视器提供一系列硬件模拟(Emulation),使得虚拟机以为自己独占硬件设备,并认为自己与硬件直接交互,其实是与QEMU模拟出来的硬件交互。该虚拟机监视器模拟的硬件包括硬盘、网卡、CPU、CD-ROM、音频设备和USB设备等。
有了KVM之后,GuestOS的CPU指令不用再经过QEMU的翻译便可直接运行,大大提高了运行速度。但KVM缺少虚拟设备的模拟,所以它结合QEMU才能构成一套完整的虚拟化技术,也就是我们通常所说的QEMU-KVM解决方案。QEMU和KVM整合之后,CPU的性能问题得到了解决。另外,QEMU还会模拟其他硬件,如网络、磁盘等。同样,全虚拟化的方式也会影响这些设备的性能,于是QEMU采用类虚拟化的方式,让GuestOS加载特殊的驱动来实现硬件虚拟化。总体来说,KVM提供CPU虚拟化,而QEMU实现除CPU之外的其他硬件的虚拟化。
2.5.5 NEMU
QEMU一直是事实上的开源虚拟机管理程序标准,它的目标是尽可能通用,广泛支持模拟多种平台和多种设备的功能,并能够在大量硬件平台上运行。这就导致QEMU代码库十分庞大、繁杂,同时也放大了QEMU的安全漏洞。近年来,云中心不时爆出的安全漏洞,在很大程度上是QEMU相关漏洞。
NEMU 脱胎于性能强大又稳定的 QEMU 代码库,在此基础上只考虑特定的硬件架构和平台(目前只支持在近期版本的64位Intel芯片和ARM芯片上运行),这就使得NEMU无须关注无关的功能和硬件架构模拟,不仅简化了代码库,降低了复杂性,同时也缩小了攻击面。
2.5.6 Firecracker
当前云计算中对软件运行环境的模拟有容器和虚拟机两种重要的形态,其中容器具有启动快和资源利用率高的优点,但是安全性广为诟病;而虚拟机可以完整地模拟计算机结构,具有很好的安全性,但是也导致启动慢。
为了缩减启动时间并提高安全性,亚马逊云AWS开源了其虚拟机监视器技术Firecracker。它是一个用Rust语言重新编写的虚拟机监视器,大大优化了原先的QEMU,是一种利用KVM的新虚拟化技术。Firecracker运行在用户态,基于KVM来创建并启动轻量级虚拟机。Firecracker只模拟极少的几种硬件设备,并简化了内核加载过程,使得服务在125ms时间内即可启动。目前它主要用于创建和管理多租户容器,以及基于函数的服务。
2.5.7 VirtualBox
VirtualBox是一款开源的x86虚拟机软件,是由德国 Innotek 公司开发,由Sun Microsystems公司出品的软件,使用Qt编写,在Sun Microsystems公司被Oracle收购之后,它被称为Oracle VM VirtualBox。目前VirtualBox可运行在Windows、Linux、Macintosh和Solaris等各种平台上,支持多种虚拟机,如Windows、Linux、BSD、OS/2、Solaris等虚拟机。
VirtualBox支持软件辅助全虚拟化和硬件辅助虚拟化,支持VDI、VMDK和VHD等各种镜像格式。强大的功能和简易的部署,使得VirtualBox被广泛应用于虚拟化的测试和验证工作中。
2.5.8 Libvirt
如前文所述,各种各样的虚拟化技术提供了各式各样的管理接口,当需要异构不同的虚拟化技术时,需要适配不同的接口。另外,在云计算体系结构中,云控制平台和虚拟化平台之间缺少一层资源管理。基于以上两个理由推出了Libvirt,它是一套管理虚拟化平台的开源API。
Libvirt的主要目标是为各种虚拟化提供一套统一的接口,方便用户使用统一的方式管理虚拟化资源。它包括一个API库函数、一个守护进程libvirtd和一个命令行工具virsh。目前Libvirt兼容支持QEMU、KVM、Xen、LXC、OpenVZ、VirtualBox等,它主要有以下功能。
虚拟机管理:管理整台虚拟机的生命周期。
远程支持:支持远程调用Libvirt。
存储管理:兼容多种不同的存储类型,并支持多种镜像格式。
网络管理:管理虚拟的逻辑网络接口。
Libvirt的工作机制如图2-14所示。
图 2-14
2.5.9 Vagrant
Vagrant是一款基于Ruby的工具,可用于创建和部署虚拟化环境,它依赖下层的VirtualBox或者VMware,使用Chef技术进行部署。在日常调试、运维中经常使用Vagrant,它通过Vagrantfile文件来设置全部的部署环境,可以说是第一款通过声明的方式来定义底层基础设施的工具。Vagrant的工作机制及部分命令如图2-15所示。
图 2-15
综上所述,本章介绍了虚拟化的发展历程。可以说,虚拟化的最终目标就是将应用部署为虚拟机,并把虚拟机打包成镜像。该镜像封装了应用运行中需要的全部服务,可以简化部署。在实际情况中,会将打包虚拟机镜像的服务部署到生产环境中,每个服务实例都是一台虚拟机。虚拟机镜像往往由部署流水线构建,在构建过程中包含了应用代码和服务运行时所需的任何软件依赖。当在生产环境中部署虚拟机镜像时,需要编写一个配置文件,用于指定基础镜像和运行该镜像的配置信息。
虚拟机镜像模式封装了技术栈,在镜像中包含了应用服务及所有依赖。它消除了错误来源,确保正确地安装和设置应用运行时所需的其他基础软件。一旦应用被打包成虚拟机镜像,它就会变成一个黑盒子,封装应用的整个技术栈,该镜像可以无须修改地部署在任何地方。虚拟机的另一个好处是,每个应用实例都以完全隔离的方式运行,每台虚拟机都有固定数量的CPU和内存,不能从其他应用中窃取资源。
虽然虚拟机解决了部分资源利用率的问题,但在这种模式下,每个应用仍然拥有整台虚拟机的开销,包括其操作系统,资源的利用率还未达到最大化。另外,虚拟机部署速度相对较慢,由于虚拟机镜像较大,构建虚拟机镜像往往需要几分钟的时间。同时还需要考虑系统管理的额外开销,当需要更新应用、给GuestOS和运行时打补丁时,要重新制作镜像。