2. 网络虚拟化基础
要理解 VirtIO Net 为什么能显著提升虚拟机网络性能,必须先回到网络虚拟化的底层坐标系:虚拟化到底分几类、Hypervisor 处在什么位置、I/O 设备是如何被“虚拟”出来的,以及全虚拟化与半虚拟化在路径长度和性能上的本质差异。本章把这些基础概念串成一条主线,为后续 VirtIO 队列、vring、驱动与后端实现打下认知基础。
一、虚拟化分类:从资源维度到实现层次
虚拟化本质上是对物理资源的抽象与再分配。按资源维度可分为 CPU 虚拟化、内存虚拟化、存储虚拟化和网络虚拟化;按实现层次可分为硬件辅助虚拟化、操作系统级虚拟化(容器)和 Hypervisor 虚拟化。网络虚拟化关注的是:如何让多个虚拟网络接口共享同一块物理网卡,并保证隔离、带宽与转发正确性。
- CPU 虚拟化:通过 VT-x/AMD-V 等指令集扩展,让 Guest 指令在受控环境下执行。
- 内存虚拟化:通过 EPT/NPT 实现 Guest 物理地址到 Host 物理地址的二级转换。
- 网络虚拟化:通过虚拟交换机、虚拟网卡和 I/O 虚拟化模型,把物理链路抽象为可编排的虚拟链路。
二、Hypervisor 架构:Type 1 与 Type 2
Hypervisor(虚拟机监视器)是虚拟化的核心控制层,负责资源调度、隔离与设备模拟。按部署位置分为两类:Type 1 裸金属型直接运行在硬件之上,如 KVM、Xen、ESXi;Type 2 宿主型运行在通用操作系统之上,如 VirtualBox、VMware Workstation。KVM 在 Linux 中以内核模块形式存在,兼具 Type 1 的性能特征与 Linux 生态的灵活性,是 VirtIO 最主要的落地平台。
关键结论:Hypervisor 决定了 I/O 路径的“起点”。在 KVM 中,Guest 的 virtio-net 驱动通过 vring 与 QEMU 后端交互,再由 tap 设备接入 Linux 网桥或 OVS,最终落到物理网卡。
三、I/O 虚拟化模型:从模拟到直通
I/O 虚拟化模型决定了设备访问的代价。常见模型包括:
- 全模拟(Emulation):Hypervisor 完全用软件模拟真实设备寄存器,Guest 无需改驱动,但每次 MMIO/PIO 都会触发 VM Exit,性能最差。
- 半虚拟化(Para-virtualization):Guest 安装专用驱动,通过共享内存与 Hypervisor 协作,减少陷入次数,VirtIO 即属此类。
- 设备直通(Passthrough):借助 VT-d/IOMMU 把物理设备直接分配给 Guest,性能接近原生,但牺牲了共享与迁移能力。
- SR-IOV:物理网卡虚拟出多个 VF,每个 VF 可直通给不同 Guest,兼顾性能与一定程度的共享。
下面这张图展示了 KVM 环境下从 Guest 到物理网卡的典型 I/O 数据通路,以及 VirtIO 在其中的位置:
四、全虚拟化与半虚拟化对比
全虚拟化与半虚拟化的核心差异在于“Guest 是否知情并配合”。全虚拟化对 Guest 透明,兼容性好但路径长;半虚拟化要求 Guest 安装 virtio 驱动,通过共享内存批量提交请求,显著减少 VM Exit 与中断次数。VirtIO Net 正是半虚拟化在网络设备上的标准实现。
| 对比维度 | 全虚拟化(Emulation) | 半虚拟化(VirtIO) |
|---|---|---|
| Guest 驱动 | 无需修改,使用真实设备驱动 | 需安装 virtio-net 专用驱动 |
| I/O 路径 | 每次寄存器访问触发 VM Exit | vring 批量提交,减少陷入 |
| 性能 | 较低,CPU 开销高 | 较高,接近直通水平 |
| 兼容性 | 强,支持老旧系统 | 依赖 Guest 内核支持 |
| 典型实现 | e1000 模拟网卡 | virtio-net + vhost-net |
五、案例场景:从 e1000 迁移到 virtio-net
某业务虚拟机最初使用 e1000 模拟网卡,压测时单核软中断占比超过 60%,吞吐仅 1.2 Gbps。将网卡模型改为 virtio-net 并启用 vhost-net 后,同样压力下吞吐提升到 6.8 Gbps,Host CPU 占用下降约 45%。关键改动如下:
# 查看当前网卡模型
virsh dumpxml web-vm | grep -A3 "interface type"
# 关闭虚拟机后修改网卡模型
virsh edit web-vm
<interface type='network'>
<model type='virtio'/>
<driver name='vhost' queues='4'/>
</interface>
# 启动后确认 virtio 驱动加载
ethtool -i eth0
# driver: virtio_net
# version: 1.0.0
实践提示:多队列 virtio-net 需要 Guest 内核支持,并在 XML 中配置 queues 参数;同时建议开启 vhost-net,把数据面从 QEMU 用户态下沉到内核态,进一步降低延迟。
六、常见误区与复盘
- 误区一:认为“虚拟化一定慢”。实际上半虚拟化和硬件辅助已把开销压到很低,瓶颈往往在配置而非虚拟化本身。
- 误区二:只改网卡模型却忘记安装 virtio 驱动,导致 Guest 识别不到网卡。
- 误区三:把 SR-IOV 直通当作万能方案,忽略其牺牲迁移与快照能力的代价。
- 复盘要点:先明确性能目标与兼容性约束,再在模拟、半虚拟化、直通之间做取舍;VirtIO 是共享场景下性价比最高的默认选择。