linux上真实物理网卡和虚拟网络接口设备的区别

0 阅读6分钟

linux上网卡和虚拟网络接口设备的区别 (Opus 4.6)

基本概念

┌─────────────────────────────────────────────────────────┐
│                    Linux 网络子系统                       │
│                                                         │
│   ┌─────────────────────────────────────────────────┐   │
│   │            net_device 抽象层                     │   │
│   │        (所有网络接口的统一抽象)                     │   │
│   │                                                 │   │
│   │    ┌──────────────┐    ┌──────────────────┐     │   │
│   │    │  物理网卡      │    │  虚拟网络接口设备   │     │   │
│   │    │  eth0, ens33  │    │  tap, veth, br   │     │   │
│   │    └──────┬───────┘    └────────┬─────────┘     │   │
│   │           │                     │               │   │
│   └───────────┼─────────────────────┼───────────────┘   │
│               │                     │                   │
│               ▼                     ▼                   │
│        ┌────────────┐       ┌─────────────┐            │
│        │ 硬件驱动    │       │ 内核软件实现  │            │
│        │ + 物理芯片  │       │ (纯软件)     │            │
│        └────────────┘       └─────────────┘            │
└─────────────────────────────────────────────────────────┘

在 Linux 内核中,所有网络接口(无论物理还是虚拟)都被抽象为 net_device 结构体,上层协议栈看到的接口是统一的。

Linux 真实网卡 + 虚拟网络设备 内核层次关系图: image.png

整体对比

真实网卡(Physical NIC)

例如:eth0ens1f0eno1enp*s*

本质

  • 真实存在的硬件
  • 由网卡厂商驱动控制
  • 负责把内核数据 → 物理网线 / 光纤 / 无线电发出去

特点

  1. 硬件队列(Tx/Rx Queue)
  2. 硬件 MAC
  3. 中断(数据来了触发硬件中断通知 CPU)
  4. 支持 DMA(零拷贝,直接把内存数据搬到网卡硬件)
  5. 数据真正离开本机

工作流程

应用 → 内核协议栈 → 网卡驱动 → 网卡硬件 → 物理网口 → 外部网络

虚拟网络接口(Virtual Interface)

例如:

  • veth
  • bridge
  • tap / tun
  • ovs-systemvxlangenevegre
  • dummylo

本质

  • 纯内核软件构造的假网卡
  • 没有硬件、没有芯片、没有 PHY
  • 只在内核内部 / 虚拟机 / 容器之间转发数据
  • 数据永远不直接碰物理网口

特点

  1. 没有硬件,只有软件结构(net_device)
  2. 没有硬件中断,靠软中断 / 内核线程工作
  3. 没有 DMA,靠内存拷贝
  4. 只负责内核内部的数据转发 / 隧道封装 / 跨 Namespace 通信
  5. 最终必须依赖真实网卡才能出本机

核心区别

维度物理网卡虚拟网络接口设备
硬件依赖依赖物理网卡芯片纯软件实现,无硬件
数据出口电信号/光信号发送到物理线缆数据传递给内核中另一个软件组件
驱动厂商硬件驱动(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                       │
│                                                │
└────────────────────────────────────────────────┘
类型工作层级处理的数据典型用途
TUNL3(网络层)IP 包VPN(如 OpenVPN)
TAPL2(数据链路层)以太网帧虚拟机网络(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 BridgeOVS
转发逻辑FDB + ebtablesOpenFlow 流表(可编程)
隧道支持不支持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 抽象接口