Flannel后端为UDP模式下,分析数据包的发送方式(一)
Flannel 使用的是 UDP 模式,分析发往 10.244.2.5 的数据包会从哪个网卡发出。
路由表
以下是提供的路由表:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 enp0s3
10.244.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
10.244.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0
10.244.1.0 10.244.1.0 255.255.255.0 UG 0 0 0 flannel.1
10.244.2.0 10.244.2.0 255.255.255.0 UG 0 0 0 flannel.1
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
192.168.1.1 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s3
目标是判断发往 10.244.2.5 的数据包会从哪个网卡发出,并结合 Flannel 的 UDP 模式详细讲解路由匹配规则和数据包转发过程。
Kubernetes 和 Flannel UDP 模式背景
在 Kubernetes 环境中,Flannel 是一个常用的 CNI(Container Network Interface)插件,负责为 Pod 分配 IP 地址并处理节点间通信。Flannel 支持多种后端模式,包括 VXLAN、UDP 和 host-gw。在本例中,明确使用 UDP 模式,以下是关键背景信息:
-
Pod 网络:
- 每个 Kubernetes 节点被分配一个子网,用于其上的 Pod。例如:
10.244.0.0/24:当前节点的 Pod 子网。10.244.1.0/24和10.244.2.0/24:其他节点的 Pod 子网。
- 目标 IP
10.244.2.5属于10.244.2.0/24子网,表示它是一个运行在另一个节点上的 Pod。
- 每个 Kubernetes 节点被分配一个子网,用于其上的 Pod。例如:
-
网络接口:
cni0:一个桥接接口,连接当前节点的 Pod 和主机网络。本地 Pod(10.244.0.0/24)的数据包通过cni0进入主机网络。flannel.1:Flannel 创建的虚拟接口,用于节点间通信。在 UDP 模式下,flannel.1是一个 TUN 设备,负责封装和解封装数据包。flannel0:可能是一个旧的或次要接口(视 Flannel 配置而定),在本例中可能不直接用于 UDP 模式的通信。enp0s3:节点的物理网络接口,用于节点间实际的物理网络通信。
-
Flannel UDP 模式:
- 在 UDP 模式下,Flannel 使用用户态的 UDP 封装(而不是内核态的 VXLAN)来传输数据包。
- 数据包通过
flannel.1(TUN 设备)发出,被 Flannel 的用户态进程(flanneld)封装为 UDP 数据包,然后通过节点的物理接口(如enp0s3)发送到目标节点。 - Flannel 通过 etcd 或 Kubernetes API 维护子网到节点 IP 的映射。例如,
10.244.2.0/24映射到某个节点的物理 IP(如192.168.x.x)。
-
路由表的作用:
- Flannel 配置路由表,确保 Pod 的流量可以路由到正确的接口(本地 Pod 通过
cni0,跨节点 Pod 通过flannel.1)。 - 网关地址(如
10.244.2.0)在 UDP 模式下是子网的网络地址,Flannel 的用户态进程会根据子网映射将其转换为目标节点的物理 IP。
- Flannel 配置路由表,确保 Pod 的流量可以路由到正确的接口(本地 Pod 通过
路由匹配规则(结合 Kubernetes 和 UDP 模式)
Linux 内核根据以下规则选择路由:
-
最长前缀匹配(Longest Prefix Match):
- 系统将目标 IP 地址与路由表中的
Destination和Genmask比较,选择子网掩码最长的匹配项。 - 例如,
255.255.255.0(/24)比255.255.0.0(/16)更具体,优先级更高。
- 系统将目标 IP 地址与路由表中的
-
网关(Gateway):
- 如果
Gateway是0.0.0.0,表示目标网络直接连接到指定接口(Iface),数据包直接通过该接口发送。 - 如果
Gateway是一个 IP 地址(如10.244.2.0),数据包通过指定接口发送到网关。在 Flannel UDP 模式下,网关地址通常是子网的网络地址,由flanneld进程处理。
- 如果
-
标志(Flags):
U:路由有效(Up)。G:需要通过网关转发。H:目标是一个主机(而非网络)。
-
度量值(Metric):
- 如果多条路由匹配,系统选择
Metric值最低的路由。
- 如果多条路由匹配,系统选择
-
接口(Iface):
- 指定数据包通过哪个网络接口发出。在 UDP 模式下,
flannel.1是 TUN 设备,负责将数据包交给 Flannel 的用户态进程。
- 指定数据包通过哪个网络接口发出。在 UDP 模式下,
匹配过程(针对 10.244.2.5)
我们逐条检查路由表,找出与目标 IP 10.244.2.5 匹配的路由:
-
0.0.0.0/0.0.0.0(默认路由):
- 目标网络:
0.0.0.0,子网掩码:0.0.0.0(匹配所有地址)。 - 网关:
192.168.1.1,接口:enp0s3,标志:UG。 - 这是一个默认路由,用于外部网络(如互联网)。
10.244.2.5是 Kubernetes 内部 Pod 地址,不会使用此路由。
- 目标网络:
-
10.244.0.0/255.255.255.0:
- 目标网络:
10.244.0.0,子网掩码:255.255.255.0(匹配10.244.0.0-10.244.0.255)。 - 网关:
0.0.0.0,接口:cni0,标志:U。 - 检查:
10.244.2.5不属于10.244.0.0/24,因此不匹配。 - 说明:
cni0用于本地 Pod 子网(10.244.0.0/24),即当前节点的 Pod。
- 目标网络:
-
10.244.0.0/255.255.0.0:
- 目标网络:
10.244.0.0,子网掩码:255.255.0.0(匹配10.244.0.0-10.244.255.255)。 - 网关:
0.0.0.0,接口:flannel0,标志:U。 - 检查:
10.244.2.5属于10.244.0.0/16,因此匹配。 - 说明:这是一个广义路由,可能用于 Flannel 的默认配置,但在更具体路由存在时会被忽略。
flannel0在 UDP 模式下可能不直接使用。
- 目标网络:
-
10.244.1.0/255.255.255.0:
- 目标网络:
10.244.1.0,子网掩码:255.255.255.0(匹配10.244.1.0-10.244.1.255)。 - 网关:
10.244.1.0,接口:flannel.1,标志:UG。 - 检查:
10.244.2.5不属于10.244.1.0/24,因此不匹配。
- 目标网络:
-
10.244.2.0/255.255.255.0:
- 目标网络:
10.244.2.0,子网掩码:255.255.255.0(匹配10.244.2.0-10.244.2.255)。 - 网关:
10.244.2.0,接口:flannel.1,标志:UG。 - 检查:
10.244.2.5属于10.244.2.0/24,因此匹配。 - 说明:这是 Flannel 配置的跨节点路由,
10.244.2.0/24是另一个节点的 Pod 子网。
- 目标网络:
-
192.168.1.0/255.255.255.0:
- 目标网络:
192.168.1.0,子网掩码:255.255.255.0。 - 网关:
0.0.0.0,接口:enp0s3,标志:U。 - 检查:
10.244.2.5不属于192.168.1.0/24,因此不匹配。
- 目标网络:
-
192.168.1.1/255.255.255.255:
- 目标网络:
192.168.1.1,子网掩码:255.255.255.255(仅匹配主机192.168.1.1)。 - 网关:
0.0.0.0,接口:enp0s3,标志:UH。 - 检查:
10.244.2.5不匹配,因此不适用。
- 目标网络:
选择最优路由
匹配的路由有:
- 10.244.0.0/255.255.0.0(
/16,接口:flannel0) - 10.244.2.0/255.255.255.0(
/24,接口:flannel.1)
根据 最长前缀匹配 规则:
/24(255.255.255.0)比/16(255.255.0.0)更具体,因此优先选择10.244.2.0/255.255.255.0。
该路由的细节:
- 目标网络:
10.244.2.0 - 子网掩码:
255.255.255.0 - 网关:
10.244.2.0 - 接口:
flannel.1 - 标志:
UG(需要通过网关转发)
因此,数据包将通过 flannel.1 网卡发出,网关为 10.244.2.0。
Flannel UDP 模式下的数据包转发
在 Flannel 的 UDP 模式下,数据包的转发过程如下:
-
路由决定:
- 数据包的目标 IP
10.244.2.5匹配路由10.244.2.0/24,通过flannel.1接口发出。 - 网关地址
10.244.2.0是目标子网的网络地址。在 UDP 模式下,flannel.1是一个 TUN 设备,数据包会被送入用户态的flanneld进程。
- 数据包的目标 IP
-
UDP 封装:
flanneld进程接收到数据包后,查询 etcd 或 Kubernetes API 中的子网映射,确定10.244.2.0/24对应的目标节点(例如,物理 IP 为192.168.1.x)。- 数据包被封装为 UDP 数据包,默认使用端口 8472(Flannel UDP 模式的默认端口)。
- 封装后的 UDP 数据包通过节点的物理接口(如
enp0s3)发送到目标节点的物理 IP。
-
目标节点处理:
- 目标节点上的
flanneld进程监听 UDP 端口 8472,接收到封装的数据包。 flanneld解封装数据包,提取原始 IP 数据包(目标 IP10.244.2.5)。- 数据包通过目标节点的
cni0接口转发到本地 Pod 子网(10.244.2.0/24),最终到达目标 Pod(10.244.2.5)。
- 目标节点上的
-
网关地址的特殊性:
- 路由表中的网关
10.244.2.0是一个网络地址,不是实际的主机 IP。在 UDP 模式下,flanneld负责将10.244.2.0/24映射到目标节点的物理 IP。 - 这种设计允许 Flannel 动态管理节点间的通信,而无需在路由表中直接指定目标节点的物理 IP。
- 路由表中的网关
为什么选择 flannel.1?
cni0:用于本地 Pod 子网10.244.0.0/24。10.244.2.5不在此子网,因此不会通过cni0。flannel0:匹配10.244.0.0/16,但子网掩码较短(/16),优先级低于10.244.2.0/24(/24)。此外,在 UDP 模式下,flannel.1是主要的 TUN 设备,flannel0可能是一个旧接口或次要配置。enp0s3:用于物理网络通信(如外部网络或默认路由)。Pod 间通信由 Flannel 处理,不会直接使用enp0s3。
因此,flannel.1 是正确的接口,专门用于跨节点 Pod 通信。
最终答案
发往 10.244.2.5 的数据包将通过 flannel.1 网卡发出。
总结路由匹配和 Flannel UDP 转发过程
-
路由匹配:
- 目标 IP
10.244.2.5匹配10.244.2.0/24(/24比/16更具体)。 - 路由指定通过
flannel.1接口,网关为10.244.2.0。
- 目标 IP
-
Flannel UDP 处理:
- 数据包通过
flannel.1(TUN 设备)进入用户态的flanneld进程。 flanneld根据子网映射将数据包封装为 UDP 数据包,通过物理接口(如enp0s3)发送到目标节点。- 目标节点解封装数据包并转发到目标 Pod(
10.244.2.5)。
- 数据包通过
-
Kubernetes 和 UDP 模式特性:
- UDP 模式通过用户态进程(
flanneld)处理数据包封装,性能比 VXLAN 稍低,但适用于不支持 VXLAN 的环境。 flannel.1作为 TUN 设备,负责将数据包交给flanneld进行 UDP 封装。
- UDP 模式通过用户态进程(
