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 网桥直接转发(类似交换机),无需路由。

通信流程:

  1. 当 Pod 1 (10.244.1.1) 想要发送数据包给同节点的 Pod 2 (10.244.1.2) 时,数据包会通过其 eth0 接口,经由 veth pair “网线”到达主机端的 veth 设备。
  2. 该 veth 设备将数据包发送到网桥 cni0。
  3. 网桥 cni0 学习到各个 veth 端口的 MAC 地址,扮演交换机角色。它发现目标 Pod 2 的 MAC 地址也连接在自己身上,于是直接将数据包转发到连接 Pod 2 的 veth 设备。
  4. 数据包最后通过Pod 2的 veth pair 进入其网络命名空间的 eth0 接口。

整个过程都在一个节点内部完成,不经过节点的物理网卡。 你可以把它想象成在一个局域网交换机下连接的多台电脑。


2.2 Calico方案

同节点通信:如下图所示,数据包不离开主机,通过主机内部的 veth pair和路由直接转发,因此性能非常高。

不依赖网桥,通过主机路由直接转发:

  • 每个 Pod 的 veth pair 一端(calixxxx)直接接入节点网络命名空间,Felix 会在节点路由表中添加 “Pod IP → calixxxx 设备” 的路由规则。
  • 同节点 Pod 通信时,内核根据路由表直接将数据包转发到目标 Pod 的calixxxx 设备,减少网桥转发开销。

    通信流程:

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

    阶段二:数据包转发(数据平面)

    1. Pod 1 发出请求:Pod 1 中的应用程序试图访问 Pod C 的 IP (10.244.2.3)。数据包在 Pod 1 的网络命名空间内通过其 eth0 接口发出。
    2. 进入主机网络栈:数据包通过 veth pair 的“管道”进入 Node A 的根网络命名空间。
    3. 路由查询:Node A 的内核根据目标 IP (10.244.2.3) 查询路由表。路由表匹配到学习到的路由规则:去往 10.244.2.0/24 的流量,下一跳是 192.168.1.11 (Node B的IP),通过 eth0 设备发出。
    4. 直接转发:Node A 内核根据这条路由,直接将数据包从物理网卡 eth0 发出。
    5. 关键点:这个数据包没有被封装。它的源 IP 是 Pod 1 的 IP (10.244.1.1),目标 IP 是 Pod C 的 IP (10.244.2.3)。
    6. 网络路由:底层网络(交换机、路由器)根据它们自己的路由表(这些表可能也是由 BGP 动态学习而来,或是手动配置的静态路由),将这个数据包路由到 Node B 的 IP (192.168.1.11),即最终到达 Node B 的物理网卡。
    7. 目标节点处理:Node B 的物理网卡 eth0 接收到数据包。Node B 内核检查数据包的目标 IP,发现是 10.244.2.3,这是它本地的一个 Pod IP。
    8. 本地路由查询:NodeB 内核查询其本地路由表,找到一条精确路由:10.244.2.3 dev caliYYYY scope link。这条规则的意思是:“目的地是 10.244.2.3 的流量,请直接从 caliYYYY 设备发出去”。这个 caliYYYY 就是连接 Pod B 的 veth pair 在主机端的一端。
    9. 送达目标 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 间通信的透明性。

    Logo

    码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

    更多推荐