# 现象
k8s环境,假设调用链路是A调用B。
- A调用B报超时错误
- 服务B接口监控发现延迟正常(就好像A并没有调用B一样)
- B是`php`服务,阶段性出现`php_network_getaddresses: getaddrinfo failed`报错
# 分析
## DNS问题?
先从这个报错查起`php_network_getaddresses: getaddrinfo failed`
搜索这个错误,谷歌、百度会告诉你`dns`解析的问题,解析失败会报这个错。
![image-20211231204225990](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231204226.png)
但实际上,我们不论在`pod`里面还是在`node`机器上`ping`对应访问的域名,都是可以成功解析的。
排查陷入尴尬的境地,**感觉是网络问题**,为什么呢?
- 上游请求下游,大量超时,但是下游却响应正常,感觉因为网络有问题,请求没有到达下游,或者下游返回的时候上游没有收到。
- `getaddrinfo failed`表示有时候`dns`解析有问题,但是能排除`dns`本身的问题,可能还是网络的问题,但是请求或者响应有问题。
## 网络问题?
网络问题可能是哪些问题呢?
- 带宽满了?
- 不是,检查过`node`的带宽,虽然带宽占用挺高的,但是远没有达到上限
![image-20211231210551405](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231210551.png)
- `LB`超载了?
- 不是,虽然问题期间链接数上升了不少,但是还是没有到达上限。目前主要问题是请求超时,因为请求不能快速结束,所以需要更多的链接,链接数上升也说得通。
![image-20211231211355372](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231211355.png)
## 机器问题?
- CPU、内存、负载高了?
- 不是,指标正常
![image-20211231210706177](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231210706.png)
- 看看`node`主机有没有报错?
- `demsg`,看到有如下报错:`dropping packet`不就是丢包的意思么?
![LSSHdauu1J](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231210837.png)
# 问题浮现
现在定位的问题是`conntrack table`满了,导致丢包。那`conntrack`是什么呢?
`conntrack`即[连接跟踪](https://arthurchiao.art/blog/conntrack-design-and-implementation-zh/),大概意思是Linux为每一个经过网络堆栈的数据包,生成一个新的连接记录项 (Connection entry)。此后,所有属于此连接的数据包都被唯一地分配给这个连接,并标识连接的状态。
查看`conntrack`的上限和当前值,上线是52.4w,当前已经是`52.2w`,已经接近上限了。
![image-20211231212258139](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231212258.png)
执行命令`sysctl -w net.netfilter.nf_conntrack_max=2310720`,提高上限,此时问题收敛。
**问题复盘期间**,运维同学提到`net.netfilter.nf_conntrack_max`这个值在去年的时候已经调整到`231w`了,为啥现在又变回来了?
考虑到`k8s`的`kube_proxy`组件和`conntrack`有绝对关系,然后谷歌了下,看到`kube-proxy`有几个相关的参数。
![33j87MuF5A](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231213059.png)
看了下我们`kube-proxy`的启动命令`/usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf --hostname-override=cn-beijing-xxx`,配置文件是空的,也就是都是使用这些参数的默认值,`--conntrack-max-per-core`代表每个cpu核跟踪的最大NAT数量,默认值是`32768`。我们是`16核`的机器,16*32768=`524288,524288`和系统中的`net.netfilter.nf_conntrack_max`值是一致的。
**net.netfilter.nf_conntrack_max为啥变化了呢**
运维同学很确定这个参数值在去年就修改过,这个事情我也有印象。继续谷歌,看到了这边文章[《kube-proxy conntracker设置》](https://blog.csdn.net/weixin_39961559/article/details/81637023),大概意思是,`kube-proxy`的启动参数中如果没有设置--conntrack-max参数,则对比--`conntrack-min`和--conntrack-max-per-core的值与`cpu`核数的大小取其大者返回`max`值,默认值是`32768 * CPU` 核数,**最后调用SetMax设置conntrack-max的值**。
所以是`kube-proxy`重启的时候修改了系统的`net.netfilter.nf_conntrack_max`值。这是一个坑,不踩真的不知道。
再回想,昨天运维确实升级重启过`kube-proxy`....
# 总结
- 上游请求下游,上游超时,下游响应正常,大概率是网络的问题。
- 网络的问题,是`node`主机conntrack达到上限,导致丢包,丢包导致微服务请求超时。
- `net.netfilter.nf_conntrack_max`这个参数在kube-proxy启动的时候会重新设置,所以要设置好kube-proxy启动参数。
- 再看到`php_network_getaddresses: getaddrinfo failed`报错,排除`dns`本省的问题,很可能就是网络丢包导致的
- 阿里云已经有相关监控和告警了
![image-20211231215148806](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20211231215148.png)
有疑问加站长微信联系(非本文作者)