5分钟了解k8s pod通信原理--图文篇
k8s 里的pod 互相访问,从实现原理上来说无非有2种。一种是同节点的pod访问,一个是跨节点的pod的访问,这个实现细节经常会在面试环节问到,相信大多人知其然不知其所以然,本文就用图解下相关原理。

环境信息:
- 节点 A 物理 IP:192.168.1.10,Pod 1(IP:10.244.1.1,属于子网 10.244.1.0/24),Pod 2(IP:10.244.1.2,属于子网 10.244.1.0/24);
- 节点 B 物理 IP:192.168.1.11,Pod 3(IP:10.244.2.3,属于子网 10.244.2.0/24)。
一、k8s 网络模型
1.1 k8s集群网络模型示意图
k8s的网络模型可以抽象为三层,底层是物理网卡和物理网络(大二层居多),中间层是借助CNI插件实现的数据转发和处理层,最上层是容器网络接口。

容器IP地址的规划和分配,通常是由网络插件(Flannel和Calico)负责的。本篇假设地址段为10.244.0.0/16。Node节点的IP地址和路由,通常是数据中心DHCP服务器和三层路由器负责的。

用来分配给pod的子网信息、路由条目(Calico)一般会存放在哪呢?
Flannel和Calico都会把它们存储在k8s控制面的etcd数据库中,这个数据库本来是分布式的,不需要额外部署。它们可以通过集群的ApiServer去访问。
1.2 Flannel和Calico的核心组件对比
Flannel 和 Calico 是 k8s 中最常用的两种 CNI 插件,用于实现 Pod 间的网络通信,但两者在设计理念、核心组件和实现原理上有显著差异。
Flannel 设计理念偏向 “简单易用”,组件轻量化;Calico 则追求 “高性能与强功能”,组件更复杂,支持网络策略等高级特性。

1.3 K8s 中实现原理对比
两者均遵循 K8s“每个 Pod 独立 IP、直接通信” 的网络模型,但在网络拓扑、跨节点通信、网络策略等核心功能的实现上差异显著。
下面是两者网络模型与 IP 分配的区别:
1.Flannel:
- 采用 “集中式子网分配”:集群初始化时,Flannel 会划分一个大的集群网段(如 10.244.0.0/16),由 flanneld 为每个节点分配一个子网(如节点 1 分配 10.244.1.0/24,节点 2 分配 10.244.2.0/24)。
- Pod IP 从所在节点的子网中分配,由容器运行时(如 containerd)通过 CNI 接口调用 Flannel 插件完成。
- 特点:IP 分配逻辑简单,无重叠风险,但灵活性低(子网大小固定)。
2.Calico:
- 采用 “动态 IP 池”:管理员可定义多个 IP 池(如 10.244.0.0/16、192.168.0.0/16),节点从 IP 池中动态获取子网(可配置子网大小,如 /26)。
- Pod IP 由 Calico 的 IPAM(IP 地址管理)模块分配,支持固定 IP(通过 Annotation 指定)、动态回收等高级功能。
- 特点:IP 分配更灵活,支持跨 IP 池调度,适合复杂网络场景(如多租户隔离)。
二、同节点pod 通信原理
2.1 Flannel方案

依赖虚拟网桥 cni0 实现二层转发:
- 每个 Pod 通过 veth pair 连接到节点的 cni0 网桥(Pod 内为 eth0,节点侧为 vethxxxx)。
- 同节点 Pod 通信时,数据包通过 cni0 网桥直接转发(类似交换机),无需路由。
通信流程:
- 当 Pod 1 (10.244.1.1) 想要发送数据包给同节点的 Pod 2 (10.244.1.2) 时,数据包会通过其 eth0 接口,经由 veth pair “网线”到达主机端的 veth 设备。
- 该 veth 设备将数据包发送到网桥 cni0。
- 网桥 cni0 学习到各个 veth 端口的 MAC 地址,扮演交换机角色。它发现目标 Pod 2 的 MAC 地址也连接在自己身上,于是直接将数据包转发到连接 Pod 2 的 veth 设备。
- 数据包最后通过Pod 2的 veth pair 进入其网络命名空间的 eth0 接口。
整个过程都在一个节点内部完成,不经过节点的物理网卡。 你可以把它想象成在一个局域网交换机下连接的多台电脑。
2.2 Calico方案
同节点通信:如下图所示,数据包不离开主机,通过主机内部的 veth pair和路由直接转发,因此性能非常高。

不依赖网桥,通过主机路由直接转发:
- 每个 Pod 的 veth pair 一端(calixxxx)直接接入节点网络命名空间,Felix 会在节点路由表中添加 “Pod IP → calixxxx 设备” 的路由规则。
- 同节点 Pod 通信时,内核根据路由表直接将数据包转发到目标 Pod 的calixxxx 设备,减少网桥转发开销。
通信流程:
- Pod 发出数据包:当 Pod 1 中的应用程序发起对 Pod 2 的访问时,数据包会通过其网络命名空间内(pod也有网络命名空间)的 eth0 接口发出。这个eth0 实际上是 veth pair 的一端。
- 数据包进入主机:数据包会通过 veth pair 这个“管道”,立刻出现在宿主机的根网络命名空间里,对应的设备名称通常类似于calixxxx(Calico 创建)。
- 查询路由:主机内核根据目标 IP 地址(Pod 2 的 IP) 查询路由表。Calico 的 Felix 组件会预先在路由表中配置好规则,指明去往本节点上每个 Pod 的路径。因此,系统会发现目标 Pod 2 的 IP就在本节点。
- 转发至目标 Pod:根据路由规则,数据包会被直接转发到与 Pod 2对应的 veth 设备(例如 caliyyyy)。
- 数据包送达:数据包通过 Pod 2的 veth pair 进入其网络命名空间的 eth0 接口,最终被 Pod 2 内的应用程序接收。

如何验证?
# 查看 Pod 的 IP 和网络命名空间:
kubectl get pods -o wide
# 进入节点,查看路由规则(替换为目标 Pod IP)
ip route get <Pod-B-IP>
# 查看节点上的 veth 设备与ARP代理设置:
ip link | grep cali
三、跨节点pod通信原理
3.1 Flannel方案
Flannel 支持多种后端模式实现跨节点通信,最常用的是 vxlan 模式(默认)和 host-gw 模式,两种模式的转发机制不同:
本文主要介绍vxlan 模式(Overlay 网络,默认模式)

vxlan 模式通过 “隧道封装” 技术,将 Pod 数据包包裹在宿主机的 UDP 包中传输,适合底层网络不支持跨节点路由的场景(如公有云、复杂物理网络)。
跨节点通信流程(以pod 1 到 pod 3示例):
- 环境信息:
- 节点 A 物理 IP:192.168.1.10,Pod 1(IP:10.244.1.1,属于子网 10.244.1.0/24),Pod 2(IP:10.244.1.2,属于子网 10.244.1.0/24);
- 节点 B 物理 IP:192.168.1.11,Pod 3(IP:10.244.2.3,属于子网 10.244.2.0/24)。
1. Pod 1 发送数据包:
Pod 1向 Pod 3 发送数据包,目标 IP 为 10.244.2.3,通过 Pod 内的 eth0(veth pair 一端)发送到节点 A 的虚拟网桥 cni0。
2.节点 A 路由判断:
节点 A 的内核查询路由表(由 flanneld 维护),发现目标 IP 10.244.2.3 属于节点 B 的子网,路由规则指向 “通过 flannel.1 设备转发”。
3.数据包封装:
Flannel.1 设备将原始 Pod 数据包(源 10.244.1.1,目标 10.244.2.3)封装为 UDP 。
- 外层源 IP:节点 A 的物理 IP(192.168.1.10);
- 外层目标 IP:节点 B 的物理 IP(192.168.1.11);
- 封装协议:VXLAN(通过 UDP 端口 4789 传输)
4. 物理网络传输:
封装后的数据包通过节点 A 的物理网卡(如 eth0)发送到物理网络,经交换机 / 路由器转发到节点 B 的物理网卡。
5.节点 B 解封装:
节点 B 的 flannel.1 设备接收数据包,解封装得到原始 Pod 数据包(目标 10.244.2.3)。
6. 转发到 Pod B:
节点 B 的内核查询路由表,发现目标 IP 属于本地子网,通过虚拟网桥 cni0 转发到 Pod 3 的 eth0,完成通信。
核心技术:
- vxlan 隧道设备:每个节点会创建一个虚拟隧道设备 flannel.1(VXLAN 虚拟网卡),作为 Pod 数据包的 “进出口”。
- UDP 封装:Pod 数据包会被封装在宿主机的 UDP 包中(外层 IP 为宿主机 IP,端口默认 4789),通过物理网络传输到目标节点后再解封装。
3.2 Calico方案
Calico支持IPIP(Overlay模式)和纯 BGP 模式(Underlay 网络)两种方案。
本文只讲BGP模式,它是Calico 的推荐和默认模式(在网络条件允许时)。它不进行封装,直接路由,性能更优,适合底层网络支持 BGP 的场景(如数据中心网络)。
- 关于Calico,需要了解几个核心概念:
- BGP:边界网关协议,是互联网核心的路由协议。Calico 使用它来在节点间交换路由信息,告诉对方“我这里有这些 Pod 的网段,请把发送给它们的流量发给我”。
- BGP Route Reflector:在大型集群中,为了避免节点间全互联,会使用路由反射器来集中管理和分发路由信息。
- Felix:Calico 在每个节点上的守护进程,负责编写路由规则、ACL 策略等。
- BIRD:Calico 使用的 BGP 客户端,负责与其他节点或路由反射器交换 BGP 路由信息。

一个数据包从 Pod 1 (10.244.1.1) 到 Pod 3 (10.244.2.3) 的旅程:
阶段一:路由信息分发(控制平面)
在数据通信开始之前,控制平面已经通过 BGP 协议完成了路由学习。这个过程是持续进行的:
- Node B 上的 BIRD 会向网络中的 BGP 对等体(可能是其他所有节点,或者一个集中的 Route Reflector)宣告一条路由:“目标网段 10.244.2.0/24(我的 Pod 子网)的下一跳是我 Node2 的 IP (192.168.1.11)”。
- Node A上的 BIRD 学习到这条路由,并通过 Felix 将其写入 Node A 的本地内核路由表中。这就是上图中的路由规则:10.244.2.0/24 via 192.168.1.11 dev eth0。
阶段二:数据包转发(数据平面)
- Pod 1 发出请求:Pod 1 中的应用程序试图访问 Pod C 的 IP (10.244.2.3)。数据包在 Pod 1 的网络命名空间内通过其 eth0 接口发出。
- 进入主机网络栈:数据包通过 veth pair 的“管道”进入 Node A 的根网络命名空间。
- 路由查询:Node A 的内核根据目标 IP (10.244.2.3) 查询路由表。路由表匹配到学习到的路由规则:去往 10.244.2.0/24 的流量,下一跳是 192.168.1.11 (Node B的IP),通过 eth0 设备发出。
- 直接转发:Node A 内核根据这条路由,直接将数据包从物理网卡 eth0 发出。
- 关键点:这个数据包没有被封装。它的源 IP 是 Pod 1 的 IP (10.244.1.1),目标 IP 是 Pod C 的 IP (10.244.2.3)。
- 网络路由:底层网络(交换机、路由器)根据它们自己的路由表(这些表可能也是由 BGP 动态学习而来,或是手动配置的静态路由),将这个数据包路由到 Node B 的 IP (192.168.1.11),即最终到达 Node B 的物理网卡。
- 目标节点处理:Node B 的物理网卡 eth0 接收到数据包。Node B 内核检查数据包的目标 IP,发现是 10.244.2.3,这是它本地的一个 Pod IP。
- 本地路由查询:NodeB 内核查询其本地路由表,找到一条精确路由:10.244.2.3 dev caliYYYY scope link。这条规则的意思是:“目的地是 10.244.2.3 的流量,请直接从 caliYYYY 设备发出去”。这个 caliYYYY 就是连接 Pod B 的 veth pair 在主机端的一端。
- 送达目标 Pod:数据包被转发到 caliYYYY 设备,并通过 veth pair 的“管道”进入 Pod 3 的网络命名空间,最终被 Pod 3 的应用程序接收。
- 核心技术:
- BGP 路由交换:每个节点作为 BGP “发言人”,通过 BGP 协议向集群内其他节点广播 “本节点的 Pod 子网”(如 “10.244.1.0/24 网段在节点 A”)。
- 静态路由表:每个节点的内核路由表中直接记录 “目标 Pod 子网→对应节点物理 IP” 的路由规则。
四、总结
- 同节点 Pod:通过虚拟网桥(如cni0)和 veth pair 实现二层转发,效率极高。
- 跨节点 Pod:依赖 CNI 插件实现路由:
- Overlay 模式(Flannel vxlan):通过隧道封装跨节点传输,兼容性好但有封装开销。
- 直接路由模式(Calico BGP):基于 BGP 交换路由,无封装,性能更优,适合大规模集群。
无论哪种方式,最终都满足 K8s“Pod IP 直接可达、无需 NAT” 的网络模型,确保 Pod 间通信的透明性。
更多推荐


所有评论(0)