容器拥有独立 IP,不代表它拥有一块独立物理网卡;两个容器地址能够互通,也不说明报文直接在二者之间移动。Linux 网络命名空间隔离协议栈状态,veth 搬运二层帧,bridge 或路由决定下一段路径,跨主机 overlay 还会增加外层封装。

第 08、09、10 篇给出 IP、MTU 与转发基础,第 30 和 31 篇说明主机路径与 NAT。本篇只追踪一份固定 bridge CNI 配置可能建立的对象,再计算 VXLAN 封装预算。CNI 是运行时调用网络插件的接口规范,不是一种固定数据面。

netns 隔离的是网络资源视图

Linux network_namespaces(7) 列出的隔离对象包括网络设备、IPv4/IPv6 协议栈、路由表、防火墙规则、/proc/net、端口与 socket。容器进程只看到所在命名空间里的这些对象;宿主仍负责创建连接命名空间的设备和规则。

veth 总成对出现。一端发送的帧会从另一端收到,因此常把一端移入容器 netns,另一端留在宿主并接入 bridge。veth 是一段虚拟二层链路,不负责自动分配地址、生成默认路由或提供跨主机可达性。

Linux bridge 根据目标 MAC 地址过滤和转发帧。容器与目标在同一 bridge 二层域时,路径可以是 容器 eth0 → veth → bridge → 目标 veth;目标在其他网段时,容器先把帧交给网关 MAC,再由宿主执行三层路由。二层转发和三层路由不能用“bridge 会转包”混为一谈。

模式提炼:把对象与职责一一对应

隔离 = netns;点到点搬运 = veth;同域转发 = bridge;跨网段选择 = route

容器网络故障应先确认对象是否存在、位于哪个命名空间、链路是否 up,再检查地址、邻居与路由。跳过对象层直接修改 NAT,可能掩盖更早的断点。

CNI 配置描述插件调用

CNI 1.1.0 规范定义网络配置格式、运行时调用插件的协议和结果类型。运行时执行 ADD、DEL、CHECK 等操作,插件据配置创建或检查网络对象。规范允许不同插件实现数据面,因此“使用 CNI”不能推出一定存在 bridge、VXLAN 或某条 NAT 规则。

同名素材目录中的 cni-bridge.conflist.json.txt 固定了一条教学配置:bridge plugin 创建或使用 labbr0,把容器侧 veth 接入该 bridge;host-local IPAM 从 10.22.0.0/24 分配地址,默认路由指向插件返回的网关。文件使用 .json.txt,避免 Hexo 把 JSON 当页面处理。

这份配置只够描述期望对象,不能证明插件已经执行。真实验收还需要在目标 netns 中读取地址和路由,在宿主读取 veth peer、bridge 端口与 FDB,并发送受控报文对齐两端计数。

跨主机 VXLAN 增加外层路径

RFC 7348 定义 VXLAN:VTEP 给原始以太网帧添加 VXLAN、UDP、外层 IP 和外层以太网头,远端 VTEP 按 VNI 解封装。VNI 是 24 位标识,限定 overlay 二层段;它不是路由表,也不自动发现远端端点。

在没有 VLAN 和其他扩展头的基础情形中,IPv4 underlay 的开销为:

内层以太网 14 + VXLAN 8 + UDP 8 + 外层 IPv4 20 = 50 字节

若 underlay 的三层 MTU 为 1500,外层 IP 包内最多容纳 1500 - 20 - 8 - 8 = 1464 字节的内层以太网帧;扣除内层以太网头后,容器的内层 IP MTU 上限为 1450。IPv6 外层头为 40 字节,同样条件下内层 IP MTU 为 1430。

这个算式没有计入 VLAN、IPsec、Geneve 选项或其他隧道。具体实现还可能处理 DF、分片、PMTUD 和 offload。把容器 MTU 固定写成 1450,只对上述 IPv4 VXLAN 前提成立。

模式提炼:从最外层 MTU 反推负载

内层 IP MTU = underlay L3 MTU - 外层 IP - UDP - 隧道头 - 内层二层头

每增加一层封装,都应明确它计入哪个接口的 MTU。出现“小包通、大包不通”时,需要同时检查容器接口、隧道设备和 underlay,而不是只看应用报文长度。

静态路径与 MTU 验证

path_model.py 读取固定 CNI 配置,检查 bridge、IPAM、网段、路由和 MTU,再输出同宿主路径、跨宿主 VXLAN 路径以及 IPv4/IPv6 的手算结果。

1
2
python3 source/_posts/2026-09-24-计算机网络33-容器如何联网/path_model.py --help
python3 source/_posts/2026-09-24-计算机网络33-容器如何联网/path_model.py

素材包括路径演算脚本、固定 CNI 配置、演算输出、资料记录和审阅记录。

条件、限制和反例

同一 bridge 不保证通信成功。端口状态、VLAN、邻居解析、防火墙和地址冲突都可能阻断路径。反过来,不同 bridge 的端点也可能通过路由互通。

overlay 不等于加密。VXLAN 提供封装和 VNI 隔离标识,RFC 7348 不把它定义为机密性或身份认证机制。需要加密时还要使用受验证的安全层。

静态 CNI 配置通过 JSON 检查不代表内核对象存在。构建成功也只证明页面生成,不能证明容器网络连通。

练习

练习一:underlay MTU 为 9000,外层使用 IPv6 VXLAN,另有 4 字节 VLAN 标记。按本文口径计算内层 IP MTU,并写出每项开销。

练习二:容器有地址和默认路由,但同宿主目标不通。按 netns、veth、bridge、邻居和过滤顺序列出检查项,并说明每项能排除什么。

模式速查表

现象 首查对象 不应直接归因
容器看不到接口 netns 与 CNI ADD 结果 bridge 转发表
veth 一端 down peer 与命名空间生命周期 远端路由
同宿主不通 bridge 端口、FDB、邻居、过滤 VXLAN underlay
跨宿主小包通大包失败 三层 MTU 与全部封装头 应用超时
配置文件正确但无连接 插件执行结果与内核对象 CNI 规范缺陷

官方参考资料

验证边界

已验证:Python 3 标准库读取固定 CNI 配置,对对象关系、同/跨主机路径和 VXLAN MTU 进行静态演算,验证类型为 HAND_CALC。

NOT_RUN:环境缺少 ip 及 CNI 插件,未创建 netns、veth、bridge、路由、VXLAN 或真实容器,未抓包、未验证插件 ADD/CHECK/DEL、underlay 可达性、PMTUD 和性能。补证只能在自建命名空间或专用虚拟机进行,不修改宿主默认路由。