第3章 虚拟化技术简介:硬件虚拟化、软件虚拟化与I/O虚拟化分类

虚拟化这个概念,说起来简单——就是把一份物理资源,切成多份给不同模块用。但真做起来,学问大了去了。我个人习惯把虚拟化分成三个维度看:硬件虚拟化、软件虚拟化、还有I/O虚拟化。这三者对应着CPU、内存和外部设备的不同抽象方式。

你想想看,一台物理服务器上跑多个虚拟机,每个虚拟机都觉得自己独占了一台完整的机器。这个"错觉"是怎么实现的?说白了,就是通过不同层次的虚拟化技术,把物理资源切分、隔离、再暴露给上层。

核心观点: 虚拟化的本质是对物理资源的"分时复用"+"空间隔离"。硬件虚拟化解决指令级问题,软件虚拟化解决Hypervisor调度问题,I/O虚拟化解决外设共享问题。三者缺一不可。

3.1 硬件虚拟化

先聊硬件虚拟化。2005年之前,x86架构的CPU其实是不支持虚拟化的。那时的Hypervisor想运行客户机特权指令,得靠二进制翻译——每条敏感指令都要扫描、改写,性能损耗非常大。我记得当时做嵌入式虚拟化项目,CPU跑在400MHz,启动一个Linux虚拟机要花3分钟……后来Intel和AMD分别推出了VT-x和AMD-V扩展指令集,直接在CPU层面支持了Root/Non-root模式。

硬件虚拟化的核心贡献有两块:

  • CPU虚拟化:新增VMX(Virtual Machine Extensions)指令,Hypervisor运行在VMX Root模式,客户OS运行在VMX Non-root模式。敏感指令自动触发VM-Exit,由Hypervisor接管处理。这样就不需要二进制翻译了。
  • 内存虚拟化:引入EPT(Intel Extended Page Table)或NPT(AMD Nested Page Tables)。传统软件模拟需要影子页表,每次切换虚拟机都要刷新TLB。有了EPT,硬件直接完成从GVA→GPA→HPA的两级地址转换,性能提升非常明显。
我的经验: 有一次客户报修NVMe盘在虚拟机里IOPS上不去,我排查后发现是内存虚拟化没开启EPT,导致大量TLB miss。开启后吞吐量直接翻倍。记住,做NVMe虚拟化,第一件事就是确认BIOS里VT-x和EPT都开了。

3.2 软件虚拟化

软件虚拟化指的是不依赖特殊硬件支持,完全靠软件模拟来实现虚拟化。这又分出好几个流派:

类型 原理 典型代表 性能损耗
全虚拟化(软件模拟) 二进制翻译 + 异常处理 早期VMware Workstation 高(30%~50%)
半虚拟化 修改客户OS内核,通过hypercall调用 Xen PV 中(10%~20%)
容器虚拟化 共享宿主机内核,通过cgroup/namespace隔离 Docker、Podman 低(<5%)

这里我想特别说一下半虚拟化。当年Xen火的时候,驱动都是PV(Para-Virtualized)的,也就是客户机里跑一个"瘦身版"驱动,通过hypercall主动请求Hypervisor帮忙操作硬件。这样就不需要满世界翻译指令了。但代价是——你得有客户机OS源码,或者至少能加载内核模块。我的一个教训:曾经在Windows Server 2003上强行装PV驱动,结果蓝屏一整天……

到了今天,纯软件虚拟化基本被硬件辅助虚拟化取代了。但在嵌入式场景或一些特殊硬件(比如老旧的NVMe控制器)上,软件模拟仍然是最后的手段。嗯,如果你要写一个模拟器,请一定考虑内存开销。

3.3 I/O虚拟化

I/O虚拟化是NVMe虚拟化最相关的部分。我们对外设的虚拟化,传统上有三种方式:

  1. 软件模拟(Emulation):Hypervisor劫持所有的I/O指令,在软件层模拟一个通用设备(比如e1000网卡、AHCI磁盘)。好处是兼容性好,坏处是性能差——每个I/O都要经过vmexit→处理→vmentry。
  2. 设备直通(Pass-through):把物理设备直接分配给某个虚拟机,通过IOMMU/VT-d做DMA重映射。性能接近原生,但每个物理设备只能给一个VM,无法共享。
  3. SR-IOV(Single Root I/O Virtualization):物理设备自身硬件支持虚拟化,通过PF/VF方式切分出多个轻量级虚拟功能。每个VF可以独立分配给不同VM,而且VF之间硬件隔离。这是目前NVMe虚拟化的主流方案。
注意: 设备直通虽然性能好,但如果你用Linux的VFIO直通NVMe盘,切记先检查主板BIOS里的VT-d/AMD-Vi是否开启。我遇到过几次连ACPI表都报错的案例,最后发现是BIOS里INTEL VT for Directed I/O没打开。

另外还有半虚拟化I/O(比如virtio),属于一种"告诉Hypervisor我要做I/O"的轻量协议。virtio-blk/virtio-scsi在QEMU/KVM里非常常见,性能介于模拟和直通之间。

3.4 一张图看懂分类

我把上面三种虚拟化的核心关系和经典技术画成了下面的结构图。你可以先从根节点看起,再按分支理解各自包含的关键技术。

虚拟化技术分类架构图 虚拟化技术 硬件虚拟化 CPU:VMX(VT-x/AMD-V) 内存:EPT / NPT I/O:VT-d / IOMMU 软件虚拟化 全虚拟化(二进制翻译) 半虚拟化(hypercall) 容器虚拟化(cgroup) (性能取决于是否hugepage) I/O虚拟化 模拟(Emulation) 直通(Pass-through / VFIO) 半虚拟化(virtio) SR-IOV(PF/VF) NVMe虚拟化主要依赖的路线: • 硬件资源调度 → VMX + EPT + SR-IOV • 软件辅助 → virtio-blk / nvmeof-multipath

3.5 三者的关系与选型建议

这三种虚拟化不是孤立存在的。实际系统中,它们是层层叠加的:

  • CPU虚拟化(硬件)提供了运行环境基础
  • 内存虚拟化(硬件/软件混合)管理地址空间
  • I/O虚拟化(硬件直通或SR-IOV)处理外设访问

我在做NVMe虚拟化方案时,一般会先问三个问题:

  1. 需要共享吗? 如果只给一个VM,直接VFIO直通;如果要共享,上SR-IOV。
  2. 性能要求多高? 延迟敏感场景必须SR-IOV + VF直通;普通业务virtio-blk也够用。
  3. 硬件支持吗? 检查BIOS里VT-x、EPT、VT-d是否都启用。另外NVMe控制器本身要支持SR-IOV(不是所有盘都支持)。
避坑指南: 我曾经在一批老款Intel NVMe盘上做SR-IOV实验,结果PF注册了8个VF,但VF无法attach到虚拟机——后来查勘发现固件版本不支持多VF。所以做项目前,一定先去厂商网站查NVMe设备的SR-IOV capability和固件版本。

3.6 小节

这一章我们把虚拟化技术拆成了硬件、软件、I/O三大块。硬件虚拟化解决的是"CPU和内存的隔离模拟";软件虚拟化解决的是"Hypervisor调度和客户OS适配";I/O虚拟化解决的是"外设的共享与性能"。三者的交叉点,就是我们后续要讲的NVMe虚拟化。理解这些分类,你才能针对不同的存储负载,选择正确的虚拟化路径。