线上故障,这次是kube-proxy的锅
现象
k8s环境,假设调用链路是A调用B。
- A调用B报超时错误
- 服务B接口监控发现延迟正常(就好像A并没有调用B一样)
- B是
php服务,阶段性出现php_network_getaddresses: getaddrinfo failed报错
分析
DNS问题?
先从这个报错查起php_network_getaddresses: getaddrinfo failed
搜索这个错误,谷歌、百度会告诉你dns解析的问题,解析失败会报这个错。

但实际上,我们不论在pod里面还是在node机器上ping对应访问的域名,都是可以成功解析的。
排查陷入尴尬的境地,感觉是网络问题,为什么呢?
- 上游请求下游,大量超时,但是下游却响应正常,感觉因为网络有问题,请求没有到达下游,或者下游返回的时候上游没有收到。
getaddrinfo failed表示有时候dns解析有问题,但是能排除dns本身的问题,可能还是网络的问题,但是请求或者响应有问题。
网络问题?
网络问题可能是哪些问题呢?
带宽满了?
不是,检查过
node的带宽,虽然带宽占用挺高的,但是远没有达到上限
LB超载了?不是,虽然问题期间链接数上升了不少,但是还是没有到达上限。目前主要问题是请求超时,因为请求不能快速结束,所以需要更多的链接,链接数上升也说得通。

机器问题?
CPU、内存、负载高了?
不是,指标正常

看看
node主机有没有报错?demsg,看到有如下报错:dropping packet不就是丢包的意思么?
问题浮现
现在定位的问题是conntrack table满了,导致丢包。那conntrack是什么呢?
conntrack即连接跟踪,大概意思是Linux为每一个经过网络堆栈的数据包,生成一个新的连接记录项 (Connection entry)。此后,所有属于此连接的数据包都被唯一地分配给这个连接,并标识连接的状态。
查看conntrack的上限和当前值,上线是52.4w,当前已经是52.2w,已经接近上限了。

执行命令sysctl -w net.netfilter.nf_conntrack_max=2310720,提高上限,此时问题收敛。
问题复盘期间,运维同学提到net.netfilter.nf_conntrack_max这个值在去年的时候已经调整到231w了,为啥现在又变回来了?
考虑到k8s的kube_proxy组件和conntrack有绝对关系,然后谷歌了下,看到kube-proxy有几个相关的参数。

看了下我们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设置》,大概意思是,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本省的问题,很可能就是网络丢包导致的阿里云已经有相关监控和告警了
# 现象
k8s环境,假设调用链路是A调用B。
- A调用B报超时错误
- 服务B接口监控发现延迟正常(就好像A并没有调用B一样)
- B是
php服务,阶段性出现php_network_getaddresses: getaddrinfo failed报错
分析
DNS问题?
先从这个报错查起php_network_getaddresses: getaddrinfo failed
搜索这个错误,谷歌、百度会告诉你dns解析的问题,解析失败会报这个错。

但实际上,我们不论在pod里面还是在node机器上ping对应访问的域名,都是可以成功解析的。
排查陷入尴尬的境地,感觉是网络问题,为什么呢?
- 上游请求下游,大量超时,但是下游却响应正常,感觉因为网络有问题,请求没有到达下游,或者下游返回的时候上游没有收到。
getaddrinfo failed表示有时候dns解析有问题,但是能排除dns本身的问题,可能还是网络的问题,但是请求或者响应有问题。
网络问题?
网络问题可能是哪些问题呢?
带宽满了?
不是,检查过
node的带宽,虽然带宽占用挺高的,但是远没有达到上限
LB超载了?不是,虽然问题期间链接数上升了不少,但是还是没有到达上限。目前主要问题是请求超时,因为请求不能快速结束,所以需要更多的链接,链接数上升也说得通。

机器问题?
CPU、内存、负载高了?
不是,指标正常

看看
node主机有没有报错?demsg,看到有如下报错:dropping packet不就是丢包的意思么?
问题浮现
现在定位的问题是conntrack table满了,导致丢包。那conntrack是什么呢?
conntrack即连接跟踪,大概意思是Linux为每一个经过网络堆栈的数据包,生成一个新的连接记录项 (Connection entry)。此后,所有属于此连接的数据包都被唯一地分配给这个连接,并标识连接的状态。
查看conntrack的上限和当前值,上线是52.4w,当前已经是52.2w,已经接近上限了。

执行命令sysctl -w net.netfilter.nf_conntrack_max=2310720,提高上限,此时问题收敛。
问题复盘期间,运维同学提到net.netfilter.nf_conntrack_max这个值在去年的时候已经调整到231w了,为啥现在又变回来了?
考虑到k8s的kube_proxy组件和conntrack有绝对关系,然后谷歌了下,看到kube-proxy有几个相关的参数。

看了下我们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设置》,大概意思是,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本省的问题,很可能就是网络丢包导致的阿里云已经有相关监控和告警了

本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: