两个在不同节点上的 Pod 是怎么通信的?要不要封装?源 IP 会被改吗?如果路由表里少了一条会怎样?这篇在 kind 里把这条路径的每个环节(路由、NAT、延迟、故障恢复)都直接看出来。
worker 的路由(去掉每个 Pod 的 /32):
default via 172.18.0.1 dev eth0
10.244.0.0/24 via 172.18.0.3 dev eth0
10.244.2.0/24 via 172.18.0.4 dev eth0
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.2
worker2 的路由(去掉每个 Pod 的 /32):
default via 172.18.0.1 dev eth0
10.244.0.0/24 via 172.18.0.3 dev eth0
10.244.1.0/24 via 172.18.0.2 dev eth0
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.4
worker 上除 veth 以外的网卡:lo UNKNOWN; tunl0@NONE DOWN; gre0@NONE DOWN; gretap0@NONE DOWN; erspan0@NONE DOWN; ip_vti0@NONE DOWN; ip6_vti0@NONE DOWN; sit0@NONE DOWN; ip6tnl0@NONE DOWN; ip6gre0@NONE DOWN; eth0@if414 UP(没有 vxlan / geneve / wireguard 之类的隧道设备;tunl0、gre0 等是内核自带的、状态 DOWN 的兜底设备)
Pod far 里去往 10.244.2.229 的路由:10.244.2.229 via 10.244.1.1 dev eth0 src 10.244.1.194srv 在 worker2(10.244.2.229),far 在 worker(10.244.1.194)。worker 的路由表里有 10.244.0.0/24 via 172.18.0.3 和 10.244.2.0/24 via 172.18.0.4——每个别的节点的 Pod 网段,下一跳是那个节点的 IP;worker2 对称。除了 veth,节点上只有 lo、eth0 和内核自带但 DOWN 状态的 tunl0、gre0 等兜底设备,没有 vxlan、geneve、wireguard 之类的隧道。Pod far 里去往 srv 的路由是 via 10.244.1.1 dev eth0:先到本节点,再由节点的路由表发往 172.18.0.4。(这依赖节点之间二层互通,云上常需要 VXLAN / BGP / 云路由表来补这一条。)
far 访问 srv:client=10.244.1.194(far 的 IP 是 10.244.1.194——没有被 SNAT) near 访问 srv:client=10.244.2.230 worker 上的 MASQUERADE 规则:[':KIND-MASQ-AGENT - [0:0]', '-A POSTROUTING -m addrtype ! --dst-type LOCAL -j KIND-MASQ-AGENT', '-A KIND-MASQ-AGENT -d 10.244.0.0/16 -j RETURN', '-A KIND-MASQ-AGENT -j MASQUERADE'] (这类规则只对“目的不在集群 Pod 网段”的流量做 SNAT,Pod 到 Pod 的流量不受影响)
far 访问 srv,nginx 看到 client=10.244.1.194,就是 far 自己的 IP;同节点的 near 看到 10.244.2.230。worker 上 kind 的 masq-agent 规则是:目的在 10.244.0.0/16 的直接 RETURN,其他目的才 MASQUERADE——只有出集群的流量才做 SNAT。这正是 Kubernetes 网络模型要求的:Pod 之间不经 NAT 直接通信。
near → srv(同节点):平均 0.069 ms,最大 0.161 ms far → srv(跨节点):平均 0.097 ms,最大 0.180 ms(ping 30 个包;kind 的“节点”都是同一台机器上的容器,所以延迟本来就很小)
ping 30 个包:同节点平均 0.069 ms、最大 0.161 ms;跨节点平均 0.097 ms、最大 0.180 ms,多了约 0.03 ms。kind 的节点是同一台机器上的容器,所以差别很小,这个数字只说明“多一次路由转发”,不代表真实网络。
worker 上去往 worker2 网段的路由:10.244.2.0/24 via 172.18.0.4 dev eth0 现在 far → srv:client=10.244.1.194 手动删除这条路由后立刻再访问:'wget: download timed out' 等待 kindnet 重新装上路由:7.4 秒后路由回来了;之后 far → srv:client=10.244.1.194
在 worker 上手动 ip route del 10.244.2.0/24,立刻访问 srv 得到 wget: download timed out;kindnet(DaemonSet)周期性对账,7.4 秒后把路由补回来,访问恢复。多次运行里恢复时间在 4.6~7.4 秒之间。跨节点通信完全依赖这些路由,少一条就断。