线上故障,这次是kube-proxy的锅

现象

k8s环境,假设调用链路是A调用B。

  • A调用B报超时错误
  • 服务B接口监控发现延迟正常(就好像A并没有调用B一样)
  • B是php服务,阶段性出现php_network_getaddresses: getaddrinfo failed报错

分析

DNS问题?

先从这个报错查起php_network_getaddresses: getaddrinfo failed

搜索这个错误,谷歌、百度会告诉你dns解析的问题,解析失败会报这个错。

image-20211231204225990

但实际上,我们不论在pod里面还是在node机器上ping对应访问的域名,都是可以成功解析的。

排查陷入尴尬的境地,感觉是网络问题,为什么呢?

  • 上游请求下游,大量超时,但是下游却响应正常,感觉因为网络有问题,请求没有到达下游,或者下游返回的时候上游没有收到。
  • getaddrinfo failed表示有时候dns解析有问题,但是能排除dns本身的问题,可能还是网络的问题,但是请求或者响应有问题。

网络问题?

网络问题可能是哪些问题呢?

  • 带宽满了?

    • 不是,检查过node的带宽,虽然带宽占用挺高的,但是远没有达到上限

      image-20211231210551405

  • LB超载了?

    • 不是,虽然问题期间链接数上升了不少,但是还是没有到达上限。目前主要问题是请求超时,因为请求不能快速结束,所以需要更多的链接,链接数上升也说得通。

      image-20211231211355372

机器问题?

  • CPU、内存、负载高了?

    • 不是,指标正常

      image-20211231210706177

  • 看看node主机有没有报错?

    • demsg,看到有如下报错:dropping packet不就是丢包的意思么?

      LSSHdauu1J

问题浮现

现在定位的问题是conntrack table满了,导致丢包。那conntrack是什么呢?

conntrack连接跟踪,大概意思是Linux为每一个经过网络堆栈的数据包,生成一个新的连接记录项 (Connection entry)。此后,所有属于此连接的数据包都被唯一地分配给这个连接,并标识连接的状态。

查看conntrack的上限和当前值,上线是52.4w,当前已经是52.2w,已经接近上限了。

image-20211231212258139

执行命令sysctl -w net.netfilter.nf_conntrack_max=2310720,提高上限,此时问题收敛。

问题复盘期间,运维同学提到net.netfilter.nf_conntrack_max这个值在去年的时候已经调整到231w了,为啥现在又变回来了?

考虑到k8skube_proxy组件和conntrack有绝对关系,然后谷歌了下,看到kube-proxy有几个相关的参数。

33j87MuF5A

看了下我们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本省的问题,很可能就是网络丢包导致的

  • 阿里云已经有相关监控和告警了

    image-20211231215148806# 现象

k8s环境,假设调用链路是A调用B。

  • A调用B报超时错误
  • 服务B接口监控发现延迟正常(就好像A并没有调用B一样)
  • B是php服务,阶段性出现php_network_getaddresses: getaddrinfo failed报错

分析

DNS问题?

先从这个报错查起php_network_getaddresses: getaddrinfo failed

搜索这个错误,谷歌、百度会告诉你dns解析的问题,解析失败会报这个错。

image-20211231204225990

但实际上,我们不论在pod里面还是在node机器上ping对应访问的域名,都是可以成功解析的。

排查陷入尴尬的境地,感觉是网络问题,为什么呢?

  • 上游请求下游,大量超时,但是下游却响应正常,感觉因为网络有问题,请求没有到达下游,或者下游返回的时候上游没有收到。
  • getaddrinfo failed表示有时候dns解析有问题,但是能排除dns本身的问题,可能还是网络的问题,但是请求或者响应有问题。

网络问题?

网络问题可能是哪些问题呢?

  • 带宽满了?

    • 不是,检查过node的带宽,虽然带宽占用挺高的,但是远没有达到上限

      image-20211231210551405

  • LB超载了?

    • 不是,虽然问题期间链接数上升了不少,但是还是没有到达上限。目前主要问题是请求超时,因为请求不能快速结束,所以需要更多的链接,链接数上升也说得通。

      image-20211231211355372

机器问题?

  • CPU、内存、负载高了?

    • 不是,指标正常

      image-20211231210706177

  • 看看node主机有没有报错?

    • demsg,看到有如下报错:dropping packet不就是丢包的意思么?

      LSSHdauu1J

问题浮现

现在定位的问题是conntrack table满了,导致丢包。那conntrack是什么呢?

conntrack连接跟踪,大概意思是Linux为每一个经过网络堆栈的数据包,生成一个新的连接记录项 (Connection entry)。此后,所有属于此连接的数据包都被唯一地分配给这个连接,并标识连接的状态。

查看conntrack的上限和当前值,上线是52.4w,当前已经是52.2w,已经接近上限了。

image-20211231212258139

执行命令sysctl -w net.netfilter.nf_conntrack_max=2310720,提高上限,此时问题收敛。

问题复盘期间,运维同学提到net.netfilter.nf_conntrack_max这个值在去年的时候已经调整到231w了,为啥现在又变回来了?

考虑到k8skube_proxy组件和conntrack有绝对关系,然后谷歌了下,看到kube-proxy有几个相关的参数。

33j87MuF5A

看了下我们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本省的问题,很可能就是网络丢包导致的

  • 阿里云已经有相关监控和告警了

    image-20211231215148806

本作品采用《CC 协议》,转载必须注明作者和本文链接
您的点赞、评论和关注,是我创作的不懈动力。 学无止境,让我们一起加油,在技术的胡同里越走越深!
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!