Kind 环境下 Flannel IPsec 模式跨节点通信故障排查流程

环境信息

部署方式 Docker + Kind
K8s 版本 v1.27.3
CNI Flannel IPsec 模式
节点网络 172.18.0.0/16(Docker bridge)

问题现象

同节点 Pod 通信正常,跨节点 Pod 通信卡住超时:

复制代码
# 同节点访问正常
docker exec flannel-ipsec-control-plane curl -s 10.244.0.4
PodName: Pod-1 | PodIP: eth0 10.244.0.4/24

# 跨节点访问卡住
docker exec flannel-ipsec-control-plane curl -s 10.244.1.7
# 无响应...

检查 IPsec 状态,SA 未建立:

复制代码
docker exec flannel-ipsec-control-plane ip xfrm state
# 空

排查过程

查看 Flannel 日志

control-plane 节点:

复制代码
kubectl logs -n kube-system kube-flannel-ds-cd8rf

06[CFG] loaded IKE shared key for: '172.18.0.3'
13[CFG] loaded IKE shared key for: '172.18.0.2'

07[NET] received packet: from 172.18.0.1[500] to 172.18.0.3[500] (720 bytes)
07[IKE] no IKE config found for 172.18.0.3...172.18.0.1, sending NO_PROPOSAL_CHOSEN

worker 节点:

复制代码
kubectl logs -n kube-system kube-flannel-ds-gk7pl

11[NET] sending packet: from 172.18.0.2[500] to 172.18.0.3[500] (720 bytes)
04[NET] received packet: from 172.18.0.1[500] to 172.18.0.2[500] (720 bytes)
04[IKE] no IKE config found for 172.18.0.2...172.18.0.1, sending NO_PROPOSAL_CHOSEN

发现问题

IKE 包经过 Docker bridge 时,源 IP 被 SNAT 成了网关地址。

预期源 IP 实际源 IP
172.18.0.2 (worker) 172.18.0.1 (网关)
172.18.0.3 (control-plane) 172.18.0.1 (网关)

检查 iptables NAT 规则

复制代码
iptables -t nat -L POSTROUTING -n -v

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in  out               source          destination
  706 42360 MASQUERADE 0    --  *   !br-822761cba2a3  172.18.0.0/16   0.0.0.0/0
  269 19012 MASQUERADE 0    --  *   !br-64b0f4dac739  172.18.0.0/16   0.0.0.0/0

按规则字面意思,出口不是网桥 !br-xxx 才触发 MASQUERADE,同网桥转发不应该 NAT。

但问题是 :K8s 部署时需要开启 bridge-nf-call-iptables = 1,导致网桥转发流量也会经过 iptables,触发了 MASQUERADE。

复制代码
cat /proc/sys/net/bridge/bridge-nf-call-iptables
# 1

流量示意:

bridge-nf-call-iptables=1

MASQUERADE

容器A

网桥

iptables

容器B

bridge-nf-call-iptables=0

容器A

网桥

容器B

问题原因

Kind 环境下,K8s 节点本身是 Docker 容器,通过网桥互联。bridge-nf-call-iptables = 1 导致同网桥转发的流量也经过 iptables,触发 Docker 的 MASQUERADE 规则,源 IP 被改成网关 IP(172.18.0.1),Flannel IPsec 的 IKE 协商因此失败。

:这是 Kind 环境特有的问题,kubeadm 部署的物理机/VM 环境不经过 Docker 网桥,不会遇到类似问题。

解决方案

在宿主机添加 iptables 规则,让同网段流量跳过 MASQUERADE:

复制代码
iptables -t nat -I POSTROUTING -s 172.18.0.0/16 -d 172.18.0.0/16 -j ACCEPT

规则说明:

参数 含义
-t nat 操作 NAT 表
-I POSTROUTING 插入到 POSTROUTING 链最前面(优先级最高)
-s 172.18.0.0/16 匹配源 IP
-d 172.18.0.0/16 匹配目的 IP
-j ACCEPT 直接接受,跳过后续规则

添加后验证:

复制代码
iptables -t nat -L POSTROUTING -n -v

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in  out               source          destination
   19  2648 ACCEPT     0    --  *   *                 172.18.0.0/16   172.18.0.0/16
  706 42360 MASQUERADE 0    --  *   !br-822761cba2a3  172.18.0.0/16   0.0.0.0/0
  269 19012 MASQUERADE 0    --  *   !br-64b0f4dac739  172.18.0.0/16   0.0.0.0/0

重启 Flannel 触发重新协商:

复制代码
kubectl rollout restart daemonset -n kube-system kube-flannel-ds

验证 SA 已建立:

复制代码
# docker exec flannel-ipsec-control-plane ip xfrm state
src 172.18.0.3 dst 172.18.0.2
        proto esp spi 0xc1115682 reqid 11 mode tunnel
        replay-window 0 flag af-unspec
        aead rfc4106(gcm(aes)) 0x217a8659909ac029fb600b7cab791ee5b31d3563 128
        anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
src 172.18.0.2 dst 172.18.0.3
        proto esp spi 0xc3b69836 reqid 11 mode tunnel
        replay-window 32 flag af-unspec
        aead rfc4106(gcm(aes)) 0xfaa2ea9f4bfb893623ce9fc5aac9ae6646913ee7 128
        anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
src 172.18.0.3 dst 172.18.0.2
        proto esp spi 0xc9b2e230 reqid 11 mode tunnel
        replay-window 0 flag af-unspec
        aead rfc4106(gcm(aes)) 0x93c09105fd818db55e1b2d730fd31ff989fd33c2 128
        anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
src 172.18.0.2 dst 172.18.0.3
        proto esp spi 0xc709b48b reqid 11 mode tunnel
        replay-window 32 flag af-unspec
        aead rfc4106(gcm(aes)) 0x60697edd7c58b57220c15d3b9d41851a206d4e4e 128
        anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000

跨节点 Pod 通信测试:

复制代码
docker exec flannel-ipsec-control-plane curl -s 10.244.1.7
# PodName: Pod-0 | PodIP: eth0 10.244.1.7/24
相关推荐
张忠琳5 小时前
【client-go v0.36.1】(store Part 3)Store 超深度分析 — 集成模式、完整数据流、不变量、与 DeltaFIFO 协作
云原生·kubernetes·informer·store·client-go
赵渝强老师8 小时前
【赵渝强老师】Kubernetes(K8s)中的金丝雀升级
linux·docker·云原生·容器·kubernetes
鹤落晴春8 小时前
【K8s】配置存储卷
云原生·容器·kubernetes
张忠琳10 小时前
【client-go v0.36.1】(DeltaFIFO Part 1)DeltaFIFO 超深度分析 — 模块定位、类结构、接口层次、构造与初始化
云原生·kubernetes·deltafifo·informer·client-go
阿里云云原生11 小时前
实战揭秘:如何通过 AI Agent Skill 让 K8s 应用自动接入云监控?
云原生
张忠琳13 小时前
【client-go v0.36.1】tools/cache 深度分析(下篇)— RealFIFO 深度、集成架构、生命周期、设计模式总结
云原生·kubernetes·cache·informer·client-go
张忠琳14 小时前
【client-go v0.36.1】(store Part 2)Store 超深度分析 — threadSafeMap 核心、索引体系、RV追踪、事务机制
云原生·kubernetes·informer·store·client-go
sbjdhjd15 小时前
04(上)| k8s中的微服务
微服务·云原生·kubernetes·开源·云计算·excel·kubelet
这个DBA有点耶17 小时前
时序数据库深度对比:2026 年主流 TSDB 架构演进与选型指南
数据库·sql·云原生·架构·运维开发·时序数据库
qq_4523962317 小时前
第二篇:《K8s 集群搭建:Minikube、kubeadm、Kind 对比与实操》
容器·kubernetes·kind