2、容器网络基础:Docker网络模型、网络命名空间、veth pair、网桥原理、CNM与CNI简介
在Edge AI场景中,容器网络往往决定了推理服务的时延、吞吐量以及多节点协同的效率。理解容器网络的底层机制,是正确选择bridge或host模式的前提。本章从Linux网络命名空间出发,逐步拆解veth pair、网桥(bridge)的工作原理,并梳理Docker的CNM模型与Kubernetes的CNI模型之间的差异,为后续章节的实战配置打下坚实的理论基础。
上图展示了容器网络的核心链路:每个容器拥有独立的网络命名空间,通过veth pair与宿主机上的Linux Bridge相连,Bridge再通过NAT或路由与外部网络通信。下面我们逐一深入这些组件。
2.1 网络命名空间:容器网络的隔离基石
核心原理:网络命名空间(Network Namespace,NetNS)是Linux内核提供的一种资源隔离机制,它创建了独立的网络协议栈实例。每个NetNS拥有自己的网络接口(eth0、lo)、路由表、ARP表、iptables规则以及网络栈状态。在Docker中,默认情况下每个容器都会创建一个独立的NetNS,这意味着容器内的进程看到的网络环境与宿主机完全隔离,仿佛运行在一台独立的机器上。
判断方法:在宿主机上执行 ip netns list 可以查看当前存在的网络命名空间。但Docker默认不将容器NetNS挂载到/var/run/netns目录,因此需要借助 docker inspect --format '{{.State.Pid}}' <container> 获取容器PID,然后通过 nsenter -t <PID> -n ip addr 进入该命名空间查看网络接口。例如:
# 获取容器PID
$ docker inspect --format '{{.State.Pid}}' my-container
12345
# 进入该容器的网络命名空间查看接口
$ nsenter -t 12345 -n ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
2: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
inet 172.17.0.2/16 brd 172.17.0.255 scope global eth0
实战场景:在Edge AI网关设备上,如果同时运行多个推理容器,每个容器拥有独立NetNS可以避免端口冲突和路由干扰。例如,一个容器运行RTSP视频流拉取服务(绑定554端口),另一个容器运行模型推理HTTP服务(绑定8080端口),两者互不干扰。即使其中一个容器修改了默认路由或iptables规则,也不会影响另一个容器的网络通信。
nsenter 是最直接的工具。但注意,容器内可能没有安装ip命令,此时可以在宿主机上使用 ip netns exec 方式,或者直接查看宿主机的veth对端接口。2.2 veth pair:连接容器与宿主机的虚拟网线
核心原理:veth(Virtual Ethernet)pair是成对出现的虚拟网络接口,它像一根虚拟网线,一端连接容器的NetNS(通常命名为eth0),另一端连接宿主机的NetNS(通常命名为vethXXXX)。数据从一端进入,会直接从另一端出来,没有经过物理链路。这种设计使得容器内的网络流量可以无缝地传递到宿主机网络栈中。
操作流程:当Docker创建一个bridge网络模式的容器时,其内部流程如下:
- 创建新的NetNS(通过clone或unshare系统调用)。
- 创建veth pair,得到veth0和veth1两个接口。
- 将veth1放入容器的NetNS中,并重命名为eth0。
- 将veth0留在宿主机NetNS中,并连接到docker0网桥。
- 为容器内的eth0分配IP地址(如172.17.0.2/16),并设置默认网关为172.17.0.1。
案例拆解:假设我们在Edge设备上启动一个容器,执行 docker run -d --name cam-ai nvidia/cuda:11.0。此时在宿主机上执行 ip link show,可以看到类似 veth5f3a2b@if4 的接口。其中 @if4 表示对端接口在容器内的索引号是4。通过 ethtool -S veth5f3a2b 可以查看该接口的收发字节数,用于判断容器流量是否正常。
| 接口位置 | 接口名称 | MAC地址 | IP地址 | 作用 |
|---|---|---|---|---|
| 容器内 | eth0 | 02:42:ac:11:00:02 | 172.17.0.2/16 | 容器默认网络接口 |
| 宿主机 | veth5f3a2b | 02:42:5f:3a:2b:01 | 无(二层接口) | 连接容器到网桥 |
2.3 Linux Bridge:虚拟二层交换机
核心原理:Linux Bridge(网桥)是内核中的虚拟二层交换机,它根据MAC地址表决定数据帧的转发路径。Docker默认创建一个名为docker0的网桥,IP地址为172.17.0.1/16。所有连接到docker0的容器,都处于同一个二层网络中,可以直接通过IP地址互相通信,无需经过宿主机路由。
判断方法:使用 brctl show docker0 或 bridge link show 可以查看网桥上挂载的接口。例如:
$ bridge link show docker0
5: veth5f3a2b@if4 state UP <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0
7: veth8c1d9e@if6 state UP <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0
这表示有两个veth接口连接到了docker0网桥。当容器A(172.17.0.2)向容器B(172.17.0.3)发送数据时,数据帧从veth5f3a2b进入网桥,网桥查询MAC地址表,发现目标MAC地址对应veth8c1d9e端口,于是直接将帧转发到该端口,整个过程不经过宿主机IP层。
实战场景:在Edge AI集群中,如果多个推理容器需要共享模型参数或进行分布式推理,使用bridge模式可以方便地实现容器间高速通信。例如,一个主控容器需要向3个推理容器分发视频流任务,通过docker0网桥,主控容器可以直接访问172.17.0.3、172.17.0.4、172.17.0.5等地址,时延在微秒级别。
2.4 CNM与CNI:两大容器网络模型
核心原理:CNM(Container Network Model)是Docker提出的网络模型,由Libnetwork实现。CNM定义了三个核心概念:Sandbox(沙箱,即NetNS)、Endpoint(端点,即veth的一端)和Network(网络,即网桥或overlay)。CNI(Container Network Interface)是CoreOS提出的标准,被Kubernetes采用。CNI通过插件机制(如bridge、macvlan、calico)为容器配置网络,每次创建容器时,CRI(如containerd)会调用CNI插件。
对比分析:
| 维度 | CNM(Docker) | CNI(Kubernetes) |
|---|---|---|
| 设计哲学 | 由Docker守护进程统一管理 | 由容器运行时调用外部插件 |
| 配置方式 | docker network create | CNI配置文件(.conf/.json) |
| IP分配 | 内置IPAM(IP地址管理) | 由插件实现(如host-local、dhcp) |
| 多网络支持 | 一个容器可连接多个网络 | 通过多CNI配置实现 |
| 适用场景 | 单机Docker、Docker Swarm | Kubernetes、CRI-O、containerd |
案例拆解:在Edge AI平台中,如果使用Kubernetes管理边缘节点,则必须使用CNI。例如,使用Calico CNI插件为每个Pod分配一个可路由的IP地址,实现跨节点的Pod通信。而如果使用Docker Compose管理单台Edge设备的多个容器,则CNM模型足够。一个典型的CNI配置(bridge插件)如下:
{
"cniVersion": "0.4.0",
"name": "edge-bridge",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.30.0.0/24"
}
}
该配置会创建一个名为cni0的网桥,并为容器分配10.30.0.0/24网段的IP地址。
2.5 常见误区与总结复盘
误区一:认为bridge模式比host模式更安全。实际上,bridge模式虽然提供了网络隔离,但容器内的进程仍然可以通过漏洞逃逸到宿主机。在Edge AI设备上,如果容器需要访问物理串口、CAN总线或特定PCIe设备,host模式往往是唯一选择。
误区二:混淆veth pair与网桥的功能。veth pair只是提供了一条虚拟链路,而网桥负责多端口的二层转发。没有网桥,veth pair只能实现点对点通信。
误区三:忽略MAC地址表的学习过程。当容器首次通信时,网桥需要广播ARP请求来学习MAC地址,这会产生一定的时延。在时延敏感的Edge AI场景中,可以通过静态配置ARP表或使用IPVLAN来避免。