1. 容器网络基础
容器网络是云原生基础设施的核心环节,其性能瓶颈往往源于对底层内核网络机制的理解不足。本章从容器网络模型、网络命名空间隔离原理以及 veth pair 与 bridge 的工作机制三个维度,建立容器网络的底层认知框架。
1.1 容器网络模型:CNI、Overlay 与 Underlay
容器网络模型定义了容器如何接入主机网络、如何与外部通信以及如何实现跨主机互联。主流模型分为三类:CNI(Container Network Interface)、Overlay 和 Underlay。
| 模型 | 核心原理 | 典型实现 | 性能特征 | 适用场景 |
|---|---|---|---|---|
| CNI | 插件化接口标准,由容器运行时调用插件配置网络 | Flannel、Calico、Weave | 灵活,性能取决于后端实现 | Kubernetes 生态,多租户环境 |
| Overlay | 在宿主机网络之上构建虚拟二层网络,通过隧道封装传输 | VXLAN、IPIP、Geneve | 封装开销大,吞吐下降 10%-20% | 跨主机通信,网络策略隔离 |
| Underlay | 容器直接使用宿主机物理网络地址,无额外封装 | Macvlan、IPvlan、SR-IOV | 接近原生性能,延迟低 | 高性能计算,低延迟场景 |
选型建议:Overlay 模型提供了更好的网络隔离和跨子网通信能力,但会引入额外的 CPU 开销和延迟。Underlay 模型性能最优,但要求底层网络设备支持相关协议,且 IP 地址规划受限。CNI 作为标准接口,允许在同一集群中混合使用不同后端。
1.2 网络命名空间原理
网络命名空间(Network Namespace) 是 Linux 内核提供的一种轻量级虚拟化机制,它将全局网络资源(网络设备、IP 地址、路由表、防火墙规则、socket 等)隔离为独立的实例。每个容器拥有自己的网络命名空间,从而实现网络栈的完全隔离。
网络命名空间的关键隔离资源包括:
- 网络设备:lo、eth0 等虚拟或物理设备,每个命名空间拥有独立的设备列表。
- IP 地址与路由表:独立的 IPv4/IPv6 地址分配和路由策略。
- 邻居表(ARP/NDP):独立的 MAC 地址解析缓存。
- 防火墙规则:独立的 iptables/nftables 规则集。
- Socket 连接:TCP/UDP 连接完全隔离,端口号可重叠。
- /proc/net 与 /sys/class/net:每个命名空间只能看到自己的网络状态。
内核视角:网络命名空间在内核中由
struct net 结构体表示,所有网络子系统(如 TCP/IP 协议栈、Netfilter、路由子系统)都通过 net 指针访问对应的命名空间实例。创建新命名空间时,内核会复制或共享部分全局资源(如 sysctl 参数),这为后续的容器网络性能调优提供了切入点。
网络命名空间的操作命令示例:
# 创建新的网络命名空间
ip netns add container1
# 在命名空间中执行命令
ip netns exec container1 ip addr show
# 查看所有网络命名空间
ip netns list
# 删除网络命名空间
ip netns delete container1
1.3 veth pair 与 bridge 工作原理
veth pair(Virtual Ethernet Pair) 是一对虚拟网卡,它们像一根虚拟网线连接两个网络命名空间。数据包从一端进入,内核直接将其转发到另一端,不经过物理硬件。veth pair 是容器与宿主机网络通信的基础设施。
Linux Bridge 是一个虚拟二层交换机,工作于数据链路层(L2),基于 MAC 地址表转发帧。它可以将多个 veth pair 的一端连接到同一个桥接域,实现同一宿主机上多个容器之间的直接通信。
性能陷阱:veth pair 的 MTU 默认与宿主机物理网卡一致(通常 1500),但在 Overlay 网络(如 VXLAN)中,隧道封装会额外占用 50 字节头部。如果未调整 MTU,会导致分片和重传,严重降低吞吐。调优时需将容器内 MTU 设置为 1450 或更小。
veth pair 与 bridge 的典型连接流程:
- 创建 veth pair:
ip link add veth0 type veth peer name veth1 - 将一端(veth1)移入容器命名空间:
ip link set veth1 netns container1 - 将另一端(veth0)连接到 bridge:
ip link set veth0 master br0 - 为容器内 veth1 分配 IP 地址并启用:
ip netns exec container1 ip addr add 10.0.0.2/24 dev veth1; ip netns exec container1 ip link set veth1 up - 启用 bridge 和 veth0:
ip link set br0 up; ip link set veth0 up
数据包在容器、veth pair、bridge 之间的流转路径如下图所示:
1.4 容器网络数据包完整路径
结合上述三个基础概念,一个容器发送数据到同一宿主机上另一个容器的完整路径如下:
- 应用层:容器1中的应用进程调用
send()发送数据。 - Socket 层:数据进入容器1的 Socket 缓冲区,添加传输层头部(TCP/UDP)。
- 网络层:容器1的协议栈添加 IP 头部,查询路由表,确定下一跳为直连网络(10.0.0.0/24),出口设备为 veth1。
- 邻居子系统:通过 ARP 请求获取目标 IP(10.0.0.3)对应的 MAC 地址。
- veth pair 转发:数据帧从 veth1 发出,内核直接将其注入到 veth0(宿主机端)。
- Bridge 处理:veth0 将帧交给 br0,br0 根据 MAC 地址表查找目标 MAC 对应的端口(veth2)。
- 目标 veth pair:数据帧从 veth2 进入,内核转发到 veth3(容器2端)。
- 容器2协议栈:容器2的协议栈逐层解封装,最终数据到达应用进程。
性能关键点:上述路径中,Bridge MAC 地址表查找、邻居表(ARP)缓存、veth pair 的 MTU 一致性 是常见的性能瓶颈点。后续章节将深入讲解如何通过内核参数(如
net.ipv4.neigh.default.gc_thresh*、net.bridge.bridge-nf-call-iptables)和 eBPF 观测手段来定位和优化这些环节。
1.5 本章小结
容器网络的基础由三个核心概念构成:
- 网络模型(CNI/Overlay/Underlay)决定了网络架构的灵活性与性能上限。
- 网络命名空间提供了内核级的网络隔离,是容器网络安全的基石。
- veth pair 与 bridge 实现了同一宿主机上容器间的高效通信,数据路径完全在内核空间完成。