linux上网卡和虚拟网络接口设备的区别 (Opus 4.6)
基本概念
┌─────────────────────────────────────────────────────────┐
│ Linux 网络子系统 │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ net_device 抽象层 │ │
│ │ (所有网络接口的统一抽象) │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ 物理网卡 │ │ 虚拟网络接口设备 │ │ │
│ │ │ eth0, ens33 │ │ tap, veth, br │ │ │
│ │ └──────┬───────┘ └────────┬─────────┘ │ │
│ │ │ │ │ │
│ └───────────┼─────────────────────┼───────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────┐ ┌─────────────┐ │
│ │ 硬件驱动 │ │ 内核软件实现 │ │
│ │ + 物理芯片 │ │ (纯软件) │ │
│ └────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
在 Linux 内核中,所有网络接口(无论物理还是虚拟)都被抽象为
net_device结构体,上层协议栈看到的接口是统一的。
Linux 真实网卡 + 虚拟网络设备 内核层次关系图:
整体对比
真实网卡(Physical NIC)
例如:eth0、ens1f0、eno1、enp*s*
本质
- 真实存在的硬件
- 由网卡厂商驱动控制
- 负责把内核数据 → 物理网线 / 光纤 / 无线电发出去
特点
- 有硬件队列(Tx/Rx Queue)
- 有硬件 MAC
- 有中断(数据来了触发硬件中断通知 CPU)
- 支持 DMA(零拷贝,直接把内存数据搬到网卡硬件)
- 数据真正离开本机
工作流程
应用 → 内核协议栈 → 网卡驱动 → 网卡硬件 → 物理网口 → 外部网络
虚拟网络接口(Virtual Interface)
例如:
vethbridgetap/tunovs-system、vxlan、geneve、gredummy、lo
本质
- 纯内核软件构造的假网卡
- 没有硬件、没有芯片、没有 PHY
- 只在内核内部 / 虚拟机 / 容器之间转发数据
- 数据永远不直接碰物理网口
特点
- 没有硬件,只有软件结构(net_device)
- 没有硬件中断,靠软中断 / 内核线程工作
- 没有 DMA,靠内存拷贝
- 只负责内核内部的数据转发 / 隧道封装 / 跨 Namespace 通信
- 最终必须依赖真实网卡才能出本机
核心区别
| 维度 | 物理网卡 | 虚拟网络接口设备 |
|---|---|---|
| 硬件依赖 | 依赖物理网卡芯片 | 纯软件实现,无硬件 |
| 数据出口 | 电信号/光信号发送到物理线缆 | 数据传递给内核中另一个软件组件 |
| 驱动 | 厂商硬件驱动(e1000, ixgbe, mlx5...) | 内核虚拟驱动模块 |
| 收发包 | 通过 DMA 与网卡硬件交互 | 通过内核函数调用 / 共享内存 |
| 中断 | 真实硬件中断(IRQ) | 软中断模拟(softirq) |
| 性能 | 线速,有硬件卸载能力 | 受限于 CPU 软件处理 |
| 创建方式 | 内核检测硬件自动创建 | 手动 ip link add 或程序创建 |
| 数量限制 | 受物理插槽限制 | 理论上无限制 |
分别描述
物理网卡(Physical NIC)
数据收发流程
发送:
应用数据 → 内核协议栈 → 网卡驱动 → DMA写入网卡缓冲区 → 物理介质
接收:
物理介质 → 网卡芯片 → DMA写入内核内存 → 硬中断 → 软中断/NAPI → 协议栈 → 应用
硬件卸载能力
物理网卡可以将部分计算任务卸载到硬件,减轻 CPU 负担:
| 卸载功能 | 说明 |
|---|---|
| TSO (TCP Segmentation Offload) | 网卡硬件做 TCP 分段 |
| GSO (Generic Segmentation Offload) | 通用分段卸载 |
| Checksum Offload | 网卡硬件计算校验和 |
| RSS (Receive Side Scaling) | 多队列收包,分散到多个 CPU |
| VXLAN/Geneve Offload | 硬件做隧道封装/解封装 |
| Flow Director | 硬件流分类 |
虚拟网络接口设备不具备这些硬件能力,所有处理都由 CPU 完成。
常见虚拟网络接口设备
1. TUN/TAP
┌────────────────────────────────────────────────┐
│ │
│ 用户空间进程 (如 QEMU, OpenVPN) │
│ │ │
│ │ read()/write() 通过 /dev/net/tun │
│ ▼ │
│ ┌─────────────────┐ │
│ │ TUN/TAP 设备 │ │
│ │ (内核虚拟接口) │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ 内核协议栈 / 网桥 / OVS │
│ │
└────────────────────────────────────────────────┘
| 类型 | 工作层级 | 处理的数据 | 典型用途 |
|---|---|---|---|
| TUN | L3(网络层) | IP 包 | VPN(如 OpenVPN) |
| TAP | L2(数据链路层) | 以太网帧 | 虚拟机网络(QEMU/KVM) |
关键特点:
- 一端连接内核协议栈,另一端连接用户空间进程
- 用户空间通过
open("/dev/net/tun")+read()/write()收发数据 - 每次用户空间读写都涉及系统调用和数据复制
2. veth pair
┌──────── Namespace A ────────┐ ┌──────── Namespace B ────────┐
│ │ │ │
│ ┌───────────────────┐ │ │ ┌───────────────────┐ │
│ │ veth-a │◄═══╪═════╪════▶│ veth-b │ │
│ │ (虚拟网卡) │ │ │ │ (虚拟网卡) │ │
│ └───────────────────┘ │ │ └───────────────────┘ │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ Namespace A 协议栈 │ │ Namespace B 协议栈 │
│ │ │ │
└─────────────────────────────┘ └─────────────────────────────┘
关键特点:
- 总是成对创建,像一根虚拟网线的两端
- 从一端写入的数据会从另一端读出
- 两端可以放在不同的 Network Namespace 中
- 容器网络的基础组件(Docker、Kubernetes)
- 跨 Namespace 传输时会有
skb_clone开销
3. Linux Bridge
┌───────────────────────────────────────────────────┐
│ Linux Bridge (br0) │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ port 1 │ │ port 2 │ │ port 3 │ │
│ │ (tap0) │ │ (tap1) │ │ (veth) │ │
│ └───┬────┘ └───┬────┘ └───┬────┘ │
│ │ │ │ │
│ └────────────┼────────────┘ │
│ │ │
│ MAC 地址学习 │
│ FDB 转发表 │
│ ebtables 过滤 │
│ STP 生成树(可选) │
│ │
└───────────────────────────────────────────────────┘
关键特点:
- 工作在 L2 层,纯软件实现的以太网交换机
- 维护 FDB(Forwarding Database) 表做 MAC 地址学习和转发
- 支持 ebtables/nftables 做二层过滤
- KubeVirt 中用于桥接 VM 的 tap 和 veth
4. OVS (Open vSwitch) 虚拟端口
┌───────────────────────────────────────────────────┐
│ OVS Bridge (br-int) │
│ │
│ ┌──────┐ ┌──────┐ ┌────────┐ ┌──────────┐ │
│ │ veth │ │ veth │ │ patch │ │ internal │ │
│ │ port │ │ port │ │ port │ │ port │ │
│ └──────┘ └──────┘ └────────┘ └──────────┘ │
│ │
│ OpenFlow 流表匹配 │
│ 支持 VXLAN/Geneve/GRE 隧道端口 │
│ 支持 QoS / 镜像 / LACP │
│ │
└───────────────────────────────────────────────────┘
与 Linux Bridge 的区别:
| 维度 | Linux Bridge | OVS |
|---|---|---|
| 转发逻辑 | FDB + ebtables | OpenFlow 流表(可编程) |
| 隧道支持 | 不支持 | VXLAN, Geneve, GRE |
| 控制面 | 简单 | SDN 控制器集成(OVN) |
| 性能 | 简单场景更快 | 复杂场景更优(megaflow 缓存) |
| 功能丰富度 | 基础 | 企业级特性 |
5. macvlan / ipvlan
┌─────────────────────────────────────────┐
│ 物理网卡 eth0 │
│ MAC: AA:BB:CC:DD:EE:00 │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ macvlan0 │ │ macvlan1 │ │
│ │ MAC: ...01 │ │ MAC: ...02 │ │
│ │ (独立MAC) │ │ (独立MAC) │ │
│ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────┘
| 类型 | 特点 |
|---|---|
| macvlan | 每个子接口有独立 MAC,基于 MAC 做流量分离 |
| ipvlan | 所有子接口共享父接口 MAC,基于 IP 做流量分离 |
优势: 不需要 bridge,性能比 veth pair 更好 劣势: 同一父接口的子接口之间通信受限
6. vhost-net / virtio-net(虚拟化专用)
┌──── Guest ────┐ ┌──── Host ────────────────┐
│ │ │ │
│ virtio-net │◄══════▶│ vhost-net (内核模块) │
│ (前端驱动) │ vring │ (后端驱动) │
│ │ 共享内存 │ │ │
└───────────────┘ │ ▼ │
│ tap 设备 │
│ │
└──────────────────────────┘
- virtio-net:Guest 内部的虚拟网卡驱动(前端)
- vhost-net:Host 内核中的后端,直接操作 vring,避免 QEMU 用户空间中转
在 KubeVirt + Kube-OVN 场景中的角色
设备类型 在拓扑中的位置 角色
─────────────────────────────────────────────────────────
virtio-net VM 内部 VM 看到的 "物理网卡"
tap Pod netns VM 与 Host 的数据通道
Linux Bridge Pod netns 桥接 tap 和 veth
veth pair Pod netns ↔ Host netns 跨 namespace 连接
OVS port Host netns (br-int) OVN 流表处理入口
Geneve tunnel OVS 隧道端口 VPC 跨节点通信
物理网卡 (NIC) Host 实际数据出口
一句话总结
物理网卡依赖硬件芯片通过 DMA + 中断收发数据,具备硬件卸载能力;虚拟网络接口设备是纯软件实现的
net_device,通过内核函数调用或共享内存在软件组件间传递数据包,二者对上层协议栈呈现完全相同的net_device抽象接口。