veth pair 设备
面试题
什么是 veth pair?它在 Docker 网络中扮演什么角色?如何查看和管理 veth 设备?
标准答案
veth pair(Virtual Ethernet Pair)是 Linux 内核中的虚拟网络设备,由一对虚拟网卡组成,是 Docker 容器网络通信的核心通道。
什么是 veth pair
# veth pair 是一对虚拟以太网卡
# 像一根"虚拟网线"
# 一端发送的数据,另一端立即收到
# visual:
# [容器A:eth0] ===[网线]=== [宿主机:vethXXX]
# [容器B:eth0] ===[网线]=== [宿主机:vethYYY]
veth pair 的特性
# 1. 成对出现
# 创建时生成两张虚拟网卡,删除时一起删除
# 2. 数据穿透
# 一端收到的数据立即出现在另一端
# 就像一根直连的以太网线
# 3. 可跨命名空间
# 一端可以在一个网络命名空间
# 另一端可以在另一个网络命名空间
# 4. 没有物理限制
# 是纯软件实现,没有带宽、距离限制
查看 veth 设备
# 1. 查看所有 veth 设备(宿主机端)
ip link show type veth
# 输出示例
# 12: vethabc123@if11: mtu 1500
# link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
# ↑ veth 宿主机端 ↑ 容器端 if11
# 2. 查看详细统计
ip -s link show vethabc123
# 可以看到收发字节数、包数、错误数等
# 3. 查看 veth 连接到了哪个网桥
bridge link show | grep veth
# 12: vethabc123 state UP @docker0
容器内的对应设备
# 在容器内部,veth pair 的另一端显示为 eth0
docker exec my-container ip addr show eth0
# 11: eth0@if12: mtu 1500
# link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
# inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
# @if12 表示其对端是宿主机上的 ifindex 12(即 vethabc123)
veth pair 的数据传输流程
# 容器 A → 容器 B 的数据流
# 1. 容器 A 的应用发送数据
# 目标 IP: 172.17.0.3(容器 B)
# 2. 容器 A 的 eth0 发出数据包
# vethA(容器端)收到并立即传递给 vethA(宿主机端)
# 3. vethA(宿主机端)连接到 docker0 网桥
# 数据包进入 docker0
# 4. docker0 根据 MAC 地址表查找
# 目标 MAC 对应 vethB 端口
# 5. 数据包从 vethB(宿主机端)发送
# 立即出现在 vethB(容器端)
# 6. 容器 B 的 eth0 收到数据包
# 交给容器 B 的网络栈处理
# 整个过程不需要物理网卡参与
# 纯内核空间内的内存拷贝
手动创建 veth pair
# 创建一个 veth pair
sudo ip link add veth0 type veth peer name veth1
# 查看
ip link show type veth
# 12: veth0@veth1: ...
# 13: veth1@veth0: ...
# 分配 IP
sudo ip addr add 192.168.1.1/24 dev veth0
sudo ip addr add 192.168.1.2/24 dev veth1
# 启用
sudo ip link set veth0 up
sudo ip link set veth1 up
# 测试连通性
ping -c 2 192.168.1.2 -I veth0
# 删除
sudo ip link delete veth0
# 注意:删除一个,两个一起消失
将 veth 放入不同命名空间
# 创建两个网络命名空间
sudo ip netns add ns1
sudo ip netns add ns2
# 创建 veth pair
sudo ip link add veth-ns1 type veth peer name veth-ns2
# 分别放入不同命名空间
sudo ip link set veth-ns1 netns ns1
sudo ip link set veth-ns2 netns ns2
# 配置 IP
sudo ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-ns1
sudo ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth-ns2
# 启用
sudo ip netns exec ns1 ip link set veth-ns1 up
sudo ip netns exec ns2 ip link set veth-ns2 up
# 测试
sudo ip netns exec ns1 ping 10.0.0.2
# ✅ 命名空间 ns1 和 ns2 可以通过 veth pair 通信
# 这模拟了 Docker 容器网络的基本原理
性能特征
# veth pair 的性能特征
# 1. 接近于原生性能
# 纯内核实现,没有上下文切换开销
# 实测可达 ~10Gbps 以上
# 2. 主要性能损耗
# - MTU 限制需分段
# - 过多的 iptables 规则
# - 数据包在多个命名空间间穿越
# 3. 优化建议
# - 增大 MTU(9000 巨帧)
# - 减少不必要的 iptables 规则
# - 使用多队列 veth
常见问题排查
# 1. 查看 veth 连接到了哪个网桥
bridge link show
# 2. 查看容器对应的 veth
CONTAINER_IP=$(docker inspect -f '{{.NetworkSettings.IPAddress}}' my-container)
ip link show | grep -B1 "$CONTAINER_IP\|veth"
# 3. 查看 veth 的统计数据
ip -s link show vethabc123
# RX: bytes packets errors dropped
# TX: bytes packets errors dropped
# 4. 通过 veth 抓包
tcpdump -i vethabc123 -n
# 5. 找到容器 PID 对应的 veth
PID=$(docker inspect -f '{{.State.Pid}}' my-container)
cat /proc/$PID/net/if_inet6 | grep eth0
# 查看容器 eth0 的 MAC
MAC=$(docker exec my-container cat /sys/class/net/eth0/address)
# 在宿主机找这个 MAC
ip link show | grep -i "$MAC" -B1
面试官追问
问:veth pair 和 tap/tun 设备有什么区别?
答:
– veth pair:工作在第 2 层(数据链路层),成对出现,用于连接两个网络命名空间
– tap 设备:工作在第 2 层,供用户空间程序处理以太网帧(QEMU/KVM 虚拟机常用)
– tun 设备:工作在第 3 层(网络层),供用户空间程序处理 IP 包(OpenVPN 常用)
veth 是最轻量的虚拟网络设备,无需用户空间程序参与,只在内核空间完成数据转发。
问:一个容器可以有多少个 veth pair?
答:理论上可以有很多,每个额外的网络接口就是一个 veth pair。在 Docker 中,每个网络对应一个 veth pair。所以如果一个容器连接了 3 个网络,它在容器内会有 3 个 eth 设备(eth0、eth1、eth2),宿主机上就有 3 个对应的 veth 设备。
问:为什么不直接用网桥而要先用 veth pair?
答:网桥工作在宿主机的网络命名空间中。容器在独立的网络命名空间中,不能直接连接宿主机上的网桥。veth pair 的作用就是穿透命名空间边界——一端在容器命名空间,另一端在宿主机命名空间,数据可以通过 veth pair 穿越命名空间边界到达网桥。
总结
veth pair 是 Docker 网络的基础设施,它像一根”虚拟网线”连接了容器的网络命名空间和宿主机的网络栈。每启动一个容器,Docker 就创建一对 veth,一端变成容器的 eth0,另一端连到 docker0 网桥。理解 veth pair 是理解 Docker 网络底层机制的关键。


暂无评论内容