Kubernetes 网络虚拟化:Flannel CNI 底层工作原理与数据包流向深度解密 (Wiki)
在 Kubernetes 架构中,CNI(Container Network Interface)网络插件负责为整个集群的 Pod 构建一个扁平化、互通的 IP 网络。Flannel 作为最经典、最轻量级的 CNI 插件,其核心任务是为每个节点分配一个不重叠的子网,并通过网络隧道或路由技术实现“跨主机容器间直接互通”。
本知识库站在企业级网络工程师与平台运维视角,深度剖析 Flannel 的底层工作机制,并以同节点 Pod 通信和跨节点 Pod 通信(VXLAN 模式)为例,提供详尽的数据包流向与封包解包流程图。
一、 Flannel 核心架构与网段分配机制
Flannel 的核心设计思想是:“大网划分,小网独占”。
1. 全局 CIDR 与节点子网租赁
在部署集群时,我们指定了 --pod-network-cidr=10.244.0.0/16。
- 全局 Pod CIDR:
10.244.0.0/16(拥有约 65,536 个 IP)。 - 节点子网(Subnet):
flanneld启动时,会向 Kubernetes API Server(实际写入 etcd)申请租赁一个独立的子网段(通常为/24,拥有 254 个可用 IP)。k8s-master204分配子网:10.244.0.0/24k8s-worker205分配子网:10.244.1.0/24k8s-worker206分配子网:10.244.2.0/24
2. Flannel 核心后台组件
flanneld进程:运行在每个节点上的守护进程,负责向 K8s 监听节点状态,维护本地路由表、ARP 表和 FDB(转发表)。cni0网桥:本地虚拟二层交换机。每个节点启动时由 CNI 自动创建。同一个节点上的所有 Pod 都通过虚拟网卡对(veth-pair)连接到cni0上,IP 地址通常为当前节点子网的第一个 IP(例如10.244.2.1)。flannel.1设备:VXLAN 模式特有的 VTEP(VXLAN Tunnel End Point) 虚拟网卡。负责对跨节点的数据包进行硬件级别的 VXLAN 封包(Encapsulation)和解包(Decapsulation)。这里的.1代表 VXLAN 的 VNI(VXLAN Network Identifier)为 1。
二、 同节点不同 Pod 相互通信(纯二层转发)
同一台物理机(如 k8s-worker206)上的 PodA 与 PodB 相互通信时,流量完全在宿主机内部流动,不需要经过 flannel.1 进行封包,也不经过物理网卡。
1. 技术核心:veth-pair 与虚拟网桥
每个 Pod 在创建时都会生成一对虚拟网卡(veth-pair):
- 一端留在 Pod 网络命名空间内,命名为
eth0。 - 另一端延伸到宿主机的 Root 网络命名空间,绑定在
cni0网桥上,命名为vethxxxx。
2. 数据包出入流程图(同节点)
+---------------------------------------------------------------------------------+
| k8s-worker206 |
| |
| +-----------------------+ +-----------------------+ |
| | Pod A | | Pod B | |
| | 10.244.2.2 | | 10.244.2.3 | |
| +---------+-------------+ +---------+-------------+ |
| | (eth0) | (eth0) | |
| | | | |
| veth-pair veth-pair | |
| | | | |
| | (vethA) | (vethB) | |
| +---------+---------------------------------------------------+---------+ | |
| | cni0 Bridge | | |
| | (10.244.2.1) | | |
| +-----------------------------------------------------------------------+ | |
| |
+---------------------------------------------------------------------------------+
3. 数据流向步骤说明:
- PodA 发送请求:PodA (
10.244.2.2) 试图通过 TCP 访问 PodB (10.244.2.3)。由于目标 IP 在同一个子网内(10.244.2.0/24),PodA 发起 ARP 广播询问10.244.2.3的 MAC 地址。 - 网桥二层交换:ARP 请求通过
eth0传出,直接到达宿主机端的vethA。由于vethA桥接在cni0上,cni0网桥(二层交换机)在本地广播该 ARP。 - PodB 响应:PodB 收到 ARP 广播,回应其 MAC 地址。
- 单播数据传输:PodA 得到 MAC 地址后,将数据包(源 IP
10.244.2.2,目的 IP10.244.2.3)发送出去,cni0网桥根据内部的 MAC 地址表,直接将数据包单播转发到vethB,进入 PodB 的eth0。
三、 不同节点不同 Pod 相互通信(VXLAN 模式)
当跨节点通信时(例如运行在 k8s-worker205 上的 PodA 想要访问运行在 k8s-worker206 上的 PodC),流量需要跨越物理三层网络,这就需要使用 Overlay 叠加网络(VXLAN) 技术。
VXLAN 的核心原理是:“MAC in UDP”。即将 Pod 发出的原始二层以太网帧,封装在宿主机的物理 UDP 数据包中,通过物理网络传输到对端宿主机后拆封。
1. 跨节点网络拓扑与接口信息对照表
- 源端 PodA:IP =
10.244.1.10(在worker205上) - 宿主机 205 (Node1):物理 IP =
192.168.108.205,flannel.1MAC =MAC_VTEP_1 - 宿主机 206 (Node2):物理 IP =
192.168.108.206,flannel.1MAC =MAC_VTEP_2 - 终端 PodC:IP =
10.244.2.20(在worker206上)
2. 跨节点 VXLAN 数据包出入流程图(详细版)
[ Pod A (10.244.1.10) ]
|
| (veth-pair)
v
[ cni0 (10.244.1.1) ]
|
(路由转发到 flannel.1)
v
[ flannel.1 (VTEP 封包) ] <-- 1. 封装内部以太网帧
| <-- 2. 封装外部 UDP/IP 头部 (Dst: 192.168.108.206)
v
[ 物理网卡 ens33 ] =========> [ 物理网络传输 ] =========> [ 物理网卡 ens33 ]
(192.168.108.205) (UDP Port: 4789) (192.168.108.206)
|
v
[ flannel.1 (VTEP 解包) ]
|
(去外壳,还原 IP 包)
v
[ cni0 (10.244.2.1) ]
|
v
[ Pod C (10.244.2.20) ]
3. 数据包流向与封包/解包全步骤详析
第一步:PodA 发送与本地路由(在 Node1 宿主机内)
- PodA (
10.244.1.10) 想要访问 PodC (10.244.2.20)。 - PodA 发现目标 IP
10.244.2.20不在自己的本地子网(10.244.1.0/24)内,因此将数据包发送给默认网关(即cni0网桥,IP 为10.244.1.1)。 - 数据包到达宿主机 Node1 的内核协议栈。内核查看系统路由表:
内核决策:去往# 在 Node1 上查看路由 ip route # 输出中包含类似这一行: 10.244.2.0/24 dev flannel.1 proto kernel scope link src 10.244.1.010.244.2.0/24网段的数据包,应该发送给本地虚拟设备flannel.1。
第二步:flannel.1 (VTEP) 的二层封装(Overlay 开始)
- 数据包到达
flannel.1设备。因为flannel.1是一个二层设备,它需要将 IP 包封装成二层以太网帧。 - 寻找目的 VTEP MAC 地址:
flannel.1需要知道对端宿主机(Node2)上flannel.1设备的 MAC 地址。宿主机上的flanneld进程早已通过 K8s API 获取了该信息,并强行写入了本机的 ARP 缓存表中:# 在 Node1 上查看静态 ARP arp -an | grep flannel # 会有对端 VTEP MAC 的静态记录flannel.1填入内层 MAC 头部:- 内层源 MAC:
MAC_VTEP_1(Node1 的 flannel.1 硬件地址) - 内层目的 MAC:
MAC_VTEP_2(Node2 的 flannel.1 硬件地址)
- 内层源 MAC:
第三步:内核进行物理 UDP 封装(VXLAN 外壳)
- 内层帧封装完毕后,Linux 内核的 VXLAN 驱动将其装入一个标准的 UDP 数据包。
- 封装外层 UDP 头部:
- 目的端口:标准的 VXLAN 端口
4789(IANA 规定端口)。
- 目的端口:标准的 VXLAN 端口
- 封装外层 IP 头部(确定物理路由路径):
为了知道目的 VTEP MAC 对应的物理机 IP 到底是谁,内核需要查询 FDB(转发表):
由此,内核填入外层 IP 头部:# 查看 VTEP MAC 对应的物理机目标 IP bridge fdb show dev flannel.1 # 记录显示:MAC_VTEP_2 指向宿主机 192.168.108.206- 外层源 IP:
192.168.108.205(Node1 物理网卡 IP) - 外层目的 IP:
192.168.108.206(Node2 物理网卡 IP)
- 外层源 IP:
- 封装外层 MAC 头部:
根据物理主机的路由表,填入物理网卡的 MAC 地址。
第四步:跨物理网络传输
- 这个伪装成普通 UDP 包的数据,通过 Node1 的物理网卡
ens33发送出去。在物理网络设备(交换机、路由器)看来,这只是一个普通的、在192.168.108.205:xxxx与192.168.108.206:4789之间传输的 UDP 包。
第五步:Node2 接收与解包(VTEP 解封)
- 数据包到达 Node2 的物理网卡
ens33。 - 内核协议栈发现这是一个目的端口为
4789的 UDP 包,自动将其递交给内核中的 VXLAN 驱动程序。 - VXLAN 驱动程序(对应的设备是 Node2 上的
flannel.1)剥离外层 MAC、外层 IP、UDP 头部以及 VXLAN 报头,露出内层的原始以太网帧(源 IP10.244.1.10,目的 IP10.244.2.20)。
第六步:本地网桥转发(数据面收尾)
- Node2 的内核协议栈查看本地路由表:
决策:该包属于本地 Pod 网段,直接转发给虚拟网桥10.244.2.0/24 dev cni0 proto kernel scope link src 10.244.2.1cni0。 cni0网桥在本地进行标准的二层交换,通过 veth-pair 设备将原始 IP 包送入 PodC 内部。PodC 成功接收到请求。
四、 跨主机数据包结构对比图
为了能生动地在 Wiki 博客中展示,我们来看一个数据包在物理网卡上传输时的“套娃”结构变化:
| 封装层次 | 字段名称 | 填充数据 (对应本案) | 说明 |
|---|---|---|---|
| 外层 | 外层目的 MAC | Node2 物理网卡 MAC |
决定下一跳的物理流向 |
| 外层 | 外层源 MAC | Node1 物理网卡 MAC |
物理设备寻址 |
| 外层 | 外层目的 IP | 192.168.108.206 |
Node2 物理宿主机 IP |
| 外层 | 外层源 IP | 192.168.108.205 |
Node1 物理宿主机 IP |
| 外层 | 外层 UDP 端口 | 4789 |
标准 VXLAN 监听端口 |
| 中层 | VXLAN 报头 | VNI = 1 |
网络隔离标识 |
| 内层 | 内层目的 MAC | MAC_VTEP_2 (Node2 flannel.1) |
虚拟网络二层目标 |
| 内层 | 内层源 MAC | MAC_VTEP_1 (Node1 flannel.1) |
虚拟网络二层源 |
| 内层 | 内层目的 IP | 10.244.2.20 |
终端应用 PodC IP |
| 内层 | 内层源 IP | 10.244.1.10 |
源端应用 PodA IP |
| 内层 | Payload | HTTP / TCP 真实业务数据 |
原始报文体 |
五、 企业级延伸:VXLAN 模式与 Host-GW 模式对比
1. Host-GW (Host Gateway) 模式
- 工作机制:纯三层路由模式。不进行任何 VXLAN 封包,而是将每个主机的物理网卡直接作为去往对应 Pod 网段的下一跳网关。
- 路由表形态:在 Node1 上会多出一条静态路由:
10.244.2.0/24 via 192.168.108.206 dev ens33。 - 优缺点:
- 优点:性能极高。没有封装与拆封的 CPU 损耗,吞吐量和延迟接近物理网络。
- 缺点:限制严重。所有物理节点必须处于同一个二层网络(即同一个 VLAN 下,不能跨路由器/三层交换机)。
2. VXLAN 模式
- 工作机制:Overlay 叠加网络模式。
- 优缺点:
- 优点:极其灵活。支持跨三层物理网络寻址,只要宿主机之间 IP 可达,无论它们处于哪个机房或子网,都可以构建扁平化的容器网络。
- 缺点:存在性能损耗。由于每个包都要多封一层 UDP 外壳,在大流量、高吞吐场景下,会有一定的 CPU 资源消耗。
3. 企业选型建议
- 如果是自建物理机集群、或在同一个交换机下的虚拟化环境,追求极致性能,建议修改 Flannel 配置切换为 Host-GW 模式。
- 如果是公有云跨子网混合云环境、或者节点网络结构复杂,建议使用默认的 VXLAN 模式以保障最大的兼容性与连通性。
浙公网安备 33010602011771号