1. 故障背景

  单节点Kubernetes集群升级操作系统内核版本、NVIDIA驱动与CUDA后重启服务器,引发容器云管理界面访问异常。核心环境如下:

  • 组件版本:
  • Ubuntu 5.19.0-40-generic
  • Kubernetes 1.21.5, Docker 27.5.1
  • 网络插件:Flannel(Pod网段 10.233.64.0/18、Svc网段10.233.0.0/18)
  • 域名解析:CoreDNS + NodeLocalDNS
  • 代理模式:Kube-Proxy ipvs模式
  • 关键现象:
    Pod可互访Pod IP,宿主机可访问Service IP与Pod IP,但Pod内部访问Service IP超时(如 10.233.36.146:6379)。

2. 问题排查

阶段一:基础状态检查

(1)防火墙确认:ufw status 显示inactive(排除防火墙拦截)

(2)核心组件状态:

kubectl get pods -n=kube-system  # 所有组件Running
kubectl get pods -n=容器云核心组件-system  # 发现apiserver报错
  • 1.
  • 2.

(3)日志线索定位:

kubectl logs -f -n=容器云核心组件-system apiserver-68654cdc5-gg88b
  • 1.

关键报错:

Error: failed to connect to redis service, please check redis status, error: dial tcp 10.233.36.146:6379: i/o timeout
2025/07/29 17:22:08 failed to connect to redis service, please check redis status, error: dial tcp 10.233.36.146:6379: i/o timeout
  • 1.
  • 2.

结论:DNS解析正常(域名→Service IP),但Service流量不通。

(4)排查redis服务运行情况:

kubectl get pods -n=容器云公共组件-system |grrp redis
  • 1.

Redis容器运行状态正常,容器日志也正常,将Redis Svc改成NodePort模式,通过本地Redis客户端工具也能正常连接Redis服务,说明Redis服务是正常的。

阶段二:网络分层验证

  • 客户端: bubybox容器或者宿主机
  • 服务端: 集群里正常运行的Nginx服务

测试类型

操作命令

结果

推断

Pod→Pod IP

kubectl exec -it busybox -- telnet <PodIP> 80

✅ 成功

Flannel底层网络正常

Pod→Service IP

kubectl exec -it busybox -- telnet <SvcIP> 80

❌ 超时

Service层异常

宿主机→Service

telnet <SvcIP> 80

✅ 成功

kube-proxy规则对宿主机有效

关键矛盾点:

  • IPVS规则存在(ipvsadm -Ln | grep <SvcIP> 显示正常DNAT)
  • 但Pod流量无法穿透Service

注意: 如果使用的是iptables规则使用iptables-save | grep <service-name>命令排查Kube-Proxy组件是否生成了SvcIP转PodIP规则。

阶段三:抓包与内核层深挖

(1)抓包分析(Pod侧)

同时打开2个shell,都进入busybox容器内部,其中一个shell执行tcpdump命令进行抓包,另一个shell执行telnet nginx_svcIp(10.233.42.160) 80命令。

tcpdump -i any 'host 10.233.42.160 and tcp port 80' -w svc_capture.pcap
  • 1.

抓包结束后使用kubectl cp或者docker cp命令将抓的包拷贝到宿主机上再使用sftp工具下载到本地用wireshark分析,发现源地址到不了目标svcIP。

容器云网络故障深度排查:POD访问SVC超时全解析_Pod

结论:

持续发送SYN包 → 零响应(无RST/SYN-ACK),排除目标拒绝,指向中间层拦截。

源地址:Pod IP 10.233.64.250(发送方)

目标地址:Service IP 10.233.42.160

行为:

  1. 发送端发起TCP SYN请求(序号1)
  2. 连续6次重传SYN包(序号2-7),时间间隔指数级增长(1s → 3s → 7s → 15s → 31s → 64s)

关键缺失:零响应:无SYN-ACK(目标端确认)、无RST(目标拒绝)

 (2)抓包分析(服务器侧)

同时打开2个shell,一个直接在服务器上执行tcpdump命令进行抓包(直接抓nginx_podIP),另一个进入busybox容器内部执行telnet nginx_svcIp(10.233.42.160) 80命令。

tcpdump -i any 'host 10.233.64.43 and tcp port 80' -w svc_capture.pcap
  • 1.

抓包结束后使用kubectl cp或者docker cp命令将抓的包拷贝到宿主机上再使用sftp工具下载到本地用wireshark分析,根据包信息可以看到pod访问svcIp时也进行了DNAT将svcIP转成podIp了(说明kube-proxy正常),但是源Pod访问不通目标Pod。

容器云网络故障深度排查:POD访问SVC超时全解析_Pod_02

(3)内核参数致命错误

这时候怀疑是Conntrack问题,使用sysctl -p命令检查内核参数配置,发现参数加载报错。

容器云网络故障深度排查:POD访问SVC超时全解析_IP_03

这三个关键内核参数配置没有加载成功,主要是net.bridge.bridge-nf-call-iptables = 1。

net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
  • 1.
  • 2.
  • 3.

net.bridge.bridge-nf-call-iptables = 1参数失效后果。

`net.bridge.bridge-nf-call-iptables=0`  
↓  
网桥流量**绕过iptables规则**  #网桥流量绕过 iptables 后,缺失关键的路由/过滤规则(如 KUBE-MARK-MASQ 标记、KUBE-FORWARD 链的放行规则)。
  • 1.
  • 2.
  • 3.

net.bridge.bridge-nf-call-iptables = 1

  1. 作用:控制通过 Linux 网桥的 IPv4 流量是否经过 iptables 规则链(如 FORWARD、INPUT)。
  2. 启用后(=1):
  • 桥接流量(如 Pod 间通信、Service IP 访问)会被提交到 iptables 规则处理。
  • 这是 Kubernetes 的必需配置,确保 kube-proxy 的 Service 负载均衡规则(DNAT)能生效。
  1. 禁用后(=0):
  • 桥接流量绕过 iptables,导致 Service IP 的 DNAT 规则失效,Pod 访问 Service IP 必然失败。

注意:

  1. IPVS 的独立处理:
  • IPVS 工作在内核 L4 层,其 DNAT 规则(ipvsadm -Ln 看到的记录)不依赖 iptables。
  • 即使 bridge-nf-call-iptables=0,IPVS 仍能通过内核的 nf_conntrack 完成 DNAT 转换。
  1. 失效的真正表现:
  • DNAT 转换成功,但流量 无法正确路由回 Pod。
  • 原因:网桥流量绕过 iptables 后,缺失关键的路由/过滤规则(如 KUBE-MARK-MASQ 标记、KUBE-FORWARD 链的放行规则)。

net.bridge.bridge-nf-call-ip6tables = 1

  1. 作用:控制桥接的 IPv6 流量是否经过 ip6tables 规则链。
  2. 在 IPv6 环境中需启用,否则 IPv6 Service 无法正常工作。

net.bridge.bridge-nf-call-arptables = 1

  1. 作用:控制桥接的 ARP 流量是否经过 arptables 规则链。
  2. 启用后可防止 ARP 欺骗,但对 Service IP 通信影响较小。

3. 解决方案:修复内核隔离

步骤一:动态加载模块

加载内核模块:

modprobe br_netfilter # 临时加载
modprobe nf_conntrack # 临时加载
echo "br_netfilter" >> /etc/modules-load.d/k8s.conf # 永久加载
echo "nf_conntrack" >> /etc/modules-load.d/k8s.conf # 永久加载
  • 1.
  • 2.
  • 3.
  • 4.

步骤二:永久固化配置内核参数配置(实际这些参数之前都有,只不过上面那三行加载失败了)

cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf #执行sysctl -p命令不报错
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

立即生效:Pod访问Service IP恢复。

安装k8s集群建议内核参数配置:

net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
kernel.dmesg_restrict = 1
kernel.sysrq = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_local_reserved_ports = 30000-32767
vm.max_map_count = 262144
vm.swappiness = 1
fs.inotify.max_user_instances = 524288
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

modprobe br_netfilter:

  • 作用:动态加载 br_netfilter 内核模块。
  • 功能:该模块使网桥流量经过 Netfilter 框架(iptables/ip6tables),是 Kubernetes 等容器网络的基础。启用后,网桥(如 Docker 的 docker0 或 CNI 网桥)的流量会被 iptables 规则处理,确保 Service DNAT、NodePort 等生效。
  • 场景:解决同节点 Pod 互访 Service IP 失败问题(因绕过 iptables 导致 DNAT 失效)。

modprobe ip_conntrack:

  • 作用:加载 ip_conntrack 模块(新内核中名为 nf_conntrack)。
  • 功能:实现连接跟踪(Connection Tracking),记录网络连接状态(如 TCP/UDP 会话),是 NAT 和有状态防火墙的核心依赖。例如,Kubernetes Service 的 SNAT/DNAT 依赖此模块。
  • 注意:新版本内核中该模块已更名为 nf_conntrack,但 modprobe ip_conntrack 会自动加载新模块。

sysctl -p:

  • 作用:重新加载 /etc/sysctl.conf 或 /etc/sysctl.d/*.conf 中的内核参数配置。
  • 功能:使修改的 net.bridge.bridge-nf-call-iptables、net.ipv4.ip_forward 等参数立即生效。

步骤三:残余问题

向量数据库仍异常 → 定位到冗余iptables规则拦截:

容器云网络故障深度排查:POD访问SVC超时全解析_IP_04

iptables -t filter -L KUBE-EXTERNAL-SERVICES --line-numbers
iptables -t filter -D KUBE-EXTERNAL-SERVICES <行号>  # 删除冲突规则
  • 1.
  • 2.

最终状态:所有服务连通性恢复。

4. 总结

故障根因

防御措施

内核升级后模块未加载

将 br_netfilternf_conntrack 加入 /etc/modules-load.d/k8s.conf

桥接流量隔离

部署前验证 sysctl net.bridge.bridge-nf-call-iptables=1

核心启示:升级后需全链路测试网络,重点检查 内核参数 → 网桥 → kube-proxy链条。