数码在线
白蓝主题五 · 清爽阅读
首页  > 网络排错

K8s集群路由表项问题排查实录

最近在公司运维的K8s集群突然出现部分Pod无法跨节点通信的问题,服务调用超时频发。一开始怀疑是网络插件异常,但Calico日志看起来一切正常。经过层层排查,最终发现问题出在节点的路由表项上。

现象定位:从ping不通开始

某天早上,开发反馈一个部署在node-2上的服务无法被node-1上的Pod访问,但node-2自身Pod之间通信正常。第一反应是检查网络策略,确认没有配置误拦。接着在node-1上尝试直接ping node-2上Pod的IP,发现根本不通。

登录到node-1执行 ip route get 10.233.2.15(目标Pod IP),返回的结果居然是走默认网关,而不是通过flannel.1或者cali接口转发。这就奇怪了,正常应该走VXLAN隧道才对。

查看路由表,发现异常缺失

执行命令查看当前路由表:

ip route show

在正常的节点上,能看到类似这样的条目:

10.233.2.0/24 dev cali1234567890 scope link
10.233.3.0/24 via 192.168.2.10 dev flannel.1 onlink

但在出问题的node-1上,缺少了指向node-2所在子网的那条via规则。也就是说,K8s网络插件本该注入的路由项没生效。

翻日志:Calico Node状态异常

查看Calico-node容器日志:

kubectl logs -n kube-system calico-node-xxxxx -c calico-node

发现大量报错:

Failed to program rule: operation Delete failed: no such file or directory

进一步查证发现,该节点的BGP会话未完全建立。而路由项依赖BGP协议同步各节点子网信息。一旦BGP中断,新加入的节点路由就不会被广播出去。

临时修复:手动加路由

为了快速恢复业务,先手动添加缺失的路由:

ip route add 10.233.2.0/24 via 192.168.2.10 dev flannel.1 onlink

加上后,Pod立即可以互通。但这只是权宜之计,重启或网络波动后还会丢。

根因分析:节点重启后MTU不匹配

深入排查发现,该节点之前因硬件维护重启过。而重启后系统加载的网络接口MTU为1450,但Calico配置的是1440。这个微小差异导致VXLAN封装失败,进而使BGP邻居无法维持连接,最终路由项无法同步。

修改Calico的配置,统一所有节点的MTU值:

<!-- 修改 Calico 的 daemonset 或使用 kubectl patch -->
kubectl patch daemonset calico-node -n kube-system --type=strategic \
  -p '{'spec':{'template':{'spec':{'containers':[{'name':'calico-node','env':[{'name':'FELIX_VXLANMTU','value':'1450'}]}]}}}}'

预防建议:监控路由表一致性

这类问题不容易被常规健康检查捕获。建议在每个节点部署一个简单的脚本,定期校验是否存在关键CNI路由项,并上报缺失情况。

比如写个cron任务:

*/5 * * * * /bin/sh /opt/check-k8s-routes.sh

脚本内容判断是否包含集群Pod CIDR的路由项,否则告警。

一次看似复杂的网络故障,往往源于一个配置参数的偏差。路由表虽小,却是K8s网络通畅的命脉。