背景
用户是ACK+flannel的网络插件,里面有套业务的逻辑回去请求同vpc下ECS自建的nginx应用,发现目前会有大概率请求失败的情况出现
问题排查
1 处理这类问题首先我们要知道整套业务链路的网络走向,会经过哪些网口以及规则等,由于用户是pod主动访问集群外部的资源,那么简单来看整个网络链路就是:pod(客户端)---->node(pod所在的节点)---->自建nginx(目标ecs)
2 整个链路捋清楚以后就开始复现排查了,首先拿到用户集群的kubeconfig以后,进入用户指定的业务pod里面模拟测试了下,结果如图所示,果然会请求失败。
3 模拟到现象后,我们就开始做进一步分析,把pod所在节点的ECS授权以及对端ECS登录信息拿到,因为pod请求外部资源,到cb0网卡以后,会根据规则+路由通过节点的eth0 IP和对端ECS通信,所以这里我们需要拿到节点登录信息抓包看下流量是否出去了,通过抓包分析看,流量已经到节点并且送出去了,是对端ECS收到报文后没响应
4 从抓包看到现象后,其实问题范围就大概定位了,出现在目标ECS上,目标ECS不响应syn报文,一般不响应syn报文就几种情况
(1)服务器里面有安全软件,然后安全机制丢弃了这些报文(但是通过排查里面并未发现安全软件,基本可以排除)
(2)系统防火墙做了拦截,但是通过ps以及systemctl 看iptables 以及firewalld服务并未开启
(3)内核参数设置不当引发问题,我们执行netstat -s 命令查看到passive connections rejected because of time stamp统计数值非常大,并且接近于SYNs to LISTEN sockets dropped的数量,而且一直在增加
5 通过上面的抓包分析后,问题大致定位了, 我们怀疑和时间戳参数相关,因为当SYN报文的TimeStamp值小于前面成功响应的SYN报文的TimeStamp值,系统默认就会不响应该SYN请求,进一步查看用户参数配置,发现开启了tcp_tw_recycle,当tcp_tw_recycle/tcp_timestamps都开启的条件下,同一源ip主机的socket connect请求中的timestamp必须是递增的,如果不递增就会导致被丢弃,这里在nat环境下就会有不递增的坑,因为用户pod主动访问集群外部资源,网络确确实实会通过ipvs+iptables nat一次,所以符合问题现象
解决方案
服务器端不要将tcp_tw_recycle字段和tcp_timestamps字段同时设为1 ,在自建nginx的ECS侧把tcp_tw_recycle关闭后问题恢复