系统虚拟化架构如图1-4所示(以经典的“一虚多”架构为例),底层是物理硬件资源,包括三大主要硬件:CPU、内存和I/O设备。Hypervisor运行在硬件资源层上,并为虚拟机提供虚拟的硬件资源。客户机操作系统(Guest OS)运行在虚拟硬件资源上,这与传统的操作系统功能一致,管理硬件资源并为上层应用提供统一的软件接口。总览整个架构,Hypervisor应当具有两种功能:①管理虚拟环境;②管理物理资源。
(1)虚拟环境的管理: 如上所述,Hypervisor需要为虚拟机提供虚拟的硬件资源,因此至少应当包括三个模块:①CPU虚拟化模块;②内存虚拟化模块;③I/O设备虚拟化模块。除此之外,既然Hypervisor能够允许多个虚拟机同时执行,那么应当具有一套完备的调度机制来调度各虚拟机执行。考虑到一个虚拟机可能具有多个vCPU,每个vCPU独立运行,那么Hypervisor调度的基本单位应当是vCPU而非虚拟机。在云环境下,用户有时需要查询虚拟机的状态或者暂停虚拟机的执行,这也通过Hypervisor实现。为了便于用户管理自己的虚拟机,云厂商往往会提供一套完整的管理接口(例如Libvirt)支持虚拟机的创建、删除、暂停和迁移等。
(2)物理资源的管理: 除了管理虚拟环境,在某种程度上,Hypervisor还担负着操作系统的职责,即管理底层物理资源、提供安全隔离机制,以及保证某个虚拟机中的恶意代码不会破坏整个系统的稳定性。
图1-4 系统虚拟化架构
此外,一些Hypervisor还提供了调试手段和性能采集分析工具(例如KVM单元测试工具KVM-Unit-Tests ),便于开发者进行测试与评估,例如可以利用Linux提供的Perf工具查看由各种原因触发的VM-Exit(虚拟机退出)次数。
CPU、内存和I/O设备是现代计算机所必需的三大功能部件。如果系统虚拟化要构建出可运行的虚拟机,CPU虚拟化、内存虚拟化和I/O虚拟化是必要的,它们各自需要实现的功能与解决的问题简要概括如下(本书将在后续章节详细介绍)。
(1)CPU虚拟化 。在物理环境下,操作系统具有最高权限级别,可以直接访问寄存器、内存和I/O设备等关键的物理资源。但是,在虚拟环境下,物理资源由Hypervisor接管,并且Hypervisor处于最高特权级。这也就意味着客户机操作系统处于非最高特权级,无法直接访问物理资源。因此虚拟机对物理资源的访问应当触发异常,陷入Hypervisor中进行监控和模拟。这些访问物理资源的指令称为敏感指令,上述处理方式称为陷入-模拟(Trap and Emulate)。在Intel VT-x等硬件辅助虚拟化技术出现之前,软件虚拟化技术只能利用计算机体系中现有的特权级进行处理。这就要求所有的敏感指令都是特权指令,才能让Hypervisor截获所有的敏感指令。但系统中通常存在一些敏感非特权指令,它们称为“虚拟化漏洞”,CPU虚拟化的关键就是消除虚拟化漏洞。此外,中断和异常的模拟及注入也是CPU虚拟化应当考虑的问题。虚拟设备产生的中断无法像物理中断一样直接传送到物理CPU上,而需要在虚拟机陷入Hypervisor中时,将虚拟中断注入虚拟机中。虚拟机在恢复执行后发现自己有未处理的中断,从而陷入相应的中断处理程序中。
(2)内存虚拟化 。操作系统对于物理内存的使用基于两个假设:①内存都是从物理地址0开始的;②物理内存都是连续的。对于一台物理机上的多个虚拟机而言,它们共享物理内存资源,因此无法满足假设①。对于假设②,可以采用将物理内存分区的方式保证每个虚拟机看到的内存是连续的,但这样牺牲了内存使用的灵活性。因此内存虚拟化引入了GPA(Guest Physical Address,客户机物理地址)供虚拟机使用。但是,当虚拟机需要访问内存时,是无法通过GPA找到对应的数据的,需要将GPA转换为HPA(Host Physical Address,宿主机物理地址)。因此Hypervisor需要提供两个功能:①维护GPA到HPA的映射关系,即GPA→HPA;②截获虚拟机对GPA的访问,并根据上述映射关系将GPA转换为HPA。
(3)I/O虚拟化 。在物理环境下,操作系统通过I/O端口访问特定的I/O设备,称为PIO(Port I/O,端口I/O),或者将I/O设备上的寄存器映射到预留的内存地址空间进行读写,称为MMIO(Memory-Mapped I/O,内存映射I/O)。因此Hypervisor需要截获所有的PIO和MMIO操作并对其进行模拟,再将结果告知虚拟机。设备中断也类似,Hypervisor需要将中断分发到不同的虚拟机中。此外,当多个虚拟机运行在同一个物理机上时,由于I/O设备只有一份(如网卡)不可能同时供多个虚拟机使用。Hypervisor需要为每个虚拟机提供一个软件模拟的网卡(也可以采用硬件直通或者硬件辅助虚拟化的方式),这个网卡应当与现实设备具有完全相同的接口,从而允许用户无须修改客户机操作系统中原有的驱动程序就能使用这个虚拟设备。但软件模拟的方式性能较差,目前一般采用软硬件协同优化的I/O虚拟化提升性能。