KVM虚拟机的虚拟网卡(vNIC)的生成是一个由用户空间工具(QEMU) 和 Linux内核 协同工作的过程。
其核心流程可以概括为:通过 TUN/TAP
驱动在宿主机上创建一个虚拟网络端点(TAP设备),然后将这个TAP设备的一端交给虚拟机的虚拟网卡,另一端连接到宿主机的虚拟网络(如网桥)上。
下面是详细的步骤和原理分解:
核心参与者
- QEMU/KVM:虚拟机监控器(VMM),负责模拟整个虚拟机,包括虚拟硬件设备(如虚拟网卡)。
- Linux Kernel :
- KVM 模块:处理CPU和内存的虚拟化。
- TUN/TAP 驱动 :这是生成虚拟网卡的关键。它提供了创建虚拟网络设备的能力。
- 网桥驱动 或 Open vSwitch:用于将多个TAP设备(即多个虚拟机)连接在一起,构成虚拟网络。
- Libvirt(常用管理工具):通过定义XML配置文件,最终调用QEMU命令行来启动虚拟机,简化了整个过程。
虚拟网卡生成的具体步骤
第1步:定义与请求(Configuration)
当你通过 libvirt
(使用 virsh
或 virt-manager
)或直接使用 qemu
命令行启动虚拟机时,你会在配置中指定网络连接方式。最常见的是"桥接网络"或"NAT网络"。
例如,一个典型的Libvirt网络配置XML片段:
xml
<interface type='network'>
<mac address='52:54:00:8a:7b:07'/>
<source network='default'/>
<model type='virtio'/>
</interface>
<model type='virtio'/>
:指定了要模拟的网卡型号为 virtio。这是一种半虚拟化驱动,性能远优于完全模拟的e1000等网卡。
第2步:设备创建与后端建立(Creation & Backend)
当QEMU进程根据配置启动虚拟机时,会发生以下事情:
-
QEMU调用TAP驱动 :QEMU使用Linux的
ioctl()
系统调用与/dev/net/tun
设备交互,请求内核的TUN/TAP驱动程序创建一个新的TAP设备。 -
内核生成TAP设备 :TAP驱动程序在内核中创建并注册一个新的网络接口,名称通常由系统自动分配(如
tap0
,vnet0
,vnet1
)或由QEMU指定。你可以在宿主机上使用ip link
命令看到它。# 在宿主机上执行 ip link show ... 5: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UNKNOWN mode DEFAULT group default qlen 1000 link/ether fe:54:00:8a:7b:07 brd ff:ff:ff:ff:ff:ff
- 这个
vnet0
就是虚拟网卡在宿主机端的对应物。它像一个真实的网卡,一端连着宿主机的网络协议栈,另一端连着QEMU进程。
- 这个
-
QEMU与TAP设备连接 :QEMU会打开这个TAP设备文件。从此,QEMU进程可以通过文件读写操作来与这个TAP设备交换数据。发往TAP设备的数据可以被QEMU读取,QEMU写回TAP设备的数据则相当于从该设备发送出去。
第3步:前端模拟(Frontend Emulation)
在虚拟机内部,QEMU会模拟一个完整的、指定型号的网卡硬件(如virtio-net PCI设备)。
- 虚拟机操作系统启动后,会探测到这个虚拟PCI设备。
- 虚拟机内核需要安装相应的驱动程序来驱动它。对于
virtio
型号,需要加载virtio_net
驱动。 - 驱动加载后,在虚拟机内部就会出现一个普通的网络接口,通常命名为
eth0
或ens3
等。这就是虚拟机看到的"虚拟网卡"。
第4步:数据通路连接(Data Path)
至此,一条完整的数据通路已经建立:
- 虚拟机内部:应用程序通过socket发送网络数据包。
- 虚拟机内核 :数据包经过内核协议栈,由
virtio_net
驱动处理。 - QEMU进程 :
virtio_net
驱动通过一种高效的机制(如vhost-net)将数据包传递到宿主机的用户空间QEMU进程。QEMU再将数据包写入 它打开的TAP设备文件(如vnet0
)中。 - 宿主机内核 :TAP设备
vnet0
接收到数据包,仿佛是自己收到的一样,然后将其转发给其"master" (例如网桥virbr0
或br0
)。 - 虚拟交换机 :网桥根据MAC地址表进行转发。如果目的地是外部网络,数据包会从网桥的物理接口(如
ens33
)发送到物理交换机;如果目的地是同一宿主机上的另一台虚拟机,则数据包会被转发到对应的TAP设备上,完成内部交换。
反之亦然 ,从物理网络发往虚拟机的数据包,会通过物理网卡到达网桥,网桥再转发给TAP设备 vnet0
,QEMU从TAP设备文件读取到这个数据包,然后通过virtio机制注入到虚拟机内部。
总结与关键点
- 生成机制 :虚拟网卡的本质是 "前端(虚拟机内)模拟 + 后端(宿主机上)TAP设备"。
- 谁是创造者 :虚拟网卡是由 QEMU进程 请求 Linux内核的TUN/TAP驱动 动态创建的。
- 性能关键 :使用
virtio
模型和vhost-net
(内核加速模块)可以大幅降低开销,让数据通路尽可能短,避免在用户空间(QEMU)多次拷贝,从而获得接近原生的网络性能。 - 管理工具 :
libvirt
并不是必需的,但它极大地简化了调用QEMU和配置复杂网络(如自动将TAP设备加入网桥)的过程。
简单来说,KVM虚拟机的虚拟网卡是通过QEMU调用TUN/TAP驱动在宿主机上创建一个TAP设备,并将其与虚拟机内部模拟的网卡前端通过高效的virtio机制桥接起来而生成的。