内容提要
本文通过手动操作Linux网络原语(veth对、网桥、命名空间、静态路由),构建了从单节点到跨节点的容器网络,揭示了CNI(容器网络接口)的本质:它自动化了命名空间创建、IP分配和集群路由分发。文章还解释了云环境中直接路由失效的原因,以及Cilium等高级CNI如何通过VXLAN覆盖网络和eBPF解决这些问题,实现高效、可扩展的集群网络。
延伸解读
CNI 的三大核心职责
文章通过手动操作揭示了 CNI 的本质:它自动化了命名空间和 veth 对的创建、IP 地址管理(IPAM)以及集群范围内的路由分发。这些工作如果手动完成,在只有两个节点时就已经非常繁琐,而在大规模集群中几乎不可能实现。理解这三大职责,有助于排查网络问题,因为大多数故障都源于其中某一环节的失效。
云环境中的直接路由为何失效
在裸机环境中,手动配置静态路由即可实现跨节点通信,但在 AWS、GCP 等云环境中,这种直接路由方式会失效,因为云提供商不允许任意 IP 地址在网络中自由路由。这正是 Cilium 等高级 CNI 采用 VXLAN 覆盖网络的原因:通过封装原始数据包,使其看起来像普通的节点间流量,从而绕过云平台的限制。
eBPF 带来的性能优势
传统 CNI 依赖 Linux 桥接和 iptables 规则,数据包需要经过复杂的处理路径,性能随集群规模增长而下降。Cilium 通过 eBPF 将程序直接加载到内核,在网卡层面处理数据包,缩短了数据路径,实现了接近线速的性能。这种设计不仅提升了效率,还提供了更细粒度的可观测性和安全性。
Q&A
Kubernetes本身能路由网络数据包吗?
不能。Kubernetes本身不具备路由数据包的能力,它只负责调度Pod、监控健康状态和更新etcd状态。实际的数据包转发完全依赖外部插件(CNI)来实现。
什么是veth pair?它在容器网络中起什么作用?
veth pair是Linux内核提供的一对虚拟以太网接口,可以看作一根虚拟网线,数据包从一端进入会立即从另一端出来。它用于将网络命名空间连接到主机网络或其他命名空间,实现容器间的通信。
如何手动创建两个网络命名空间并用veth pair连接它们?
使用ip netns add创建命名空间,然后用ip link add veth-red type veth peer name veth-blue创建veth对,再将两端分别移入命名空间,最后在命名空间内配置IP并启用接口。具体命令包括:ip netns add red、ip link add veth-red type veth peer name veth-blue、ip link set veth-red netns red等。
为什么veth pair不适合大规模容器网络?
因为veth pair是点对点连接,随着容器数量增加,需要的连接数呈二次方增长(如4个容器需要6对,10个需要45对),导致配置复杂且难以管理。
Linux bridge在容器网络中扮演什么角色?
Linux bridge是一个软件实现的二层虚拟交换机,它连接多个网络命名空间,使它们处于同一广播域,通过MAC地址学习和ARP协议实现通信。它解决了单节点上多容器互联的问题,是传统单节点CNI的核心组件。
跨节点容器通信时,为什么直接路由会失败?
因为每个节点上的Pod子网不同,且节点上的路由表没有其他节点Pod子网的路由信息,导致数据包被发送到默认网关后无法到达目标节点,最终被丢弃。
如何手动修复跨节点容器通信?
在每个节点上添加静态路由,告知对方节点的Pod子网通过其物理IP可达。例如在VM1上执行ip route add 10.0.2.0/24 via 10.1.44.178,在VM2上执行ip route add 10.0.1.0/24 via 10.1.44.216。
CNI的核心职责有哪些?
CNI的核心职责包括:1) 创建网络命名空间、veth对并连接到网桥;2) IP地址管理(IPAM),为每个Pod分配唯一IP并确保子网不冲突;3) 集群级路由分发,自动配置路由使所有节点知道如何到达其他节点的Pod。
为什么在云环境中直接路由会失效?
因为云提供商不允许任意IP地址在其网络结构中自由路由,Pod子网(如10.0.1.0/24)对VPC无效,除非通过云控制器API显式注册,否则云网络会丢弃Pod流量。
Cilium如何解决云环境下的网络问题?
Cilium使用VXLAN/Geneve覆盖网络,将Pod数据包封装在UDP中,以节点物理IP为源目的地址,从而绕过云VPC限制;同时利用eBPF在内核层面处理数据包,替代传统的网桥和iptables,提升性能并增强可观测性。