kubernetes – 请求超时问题的分析过程

上周kubernetes集群开始出现各种超时问题,从调用链监控系统查看报错,大概表现有:

  • 域名解析失败
  • 网络调用超时
  • 滚动发布引起调用方超时

初步怀疑

观察到超时调用基本都是5秒,联想到域名解析失败的表现,怀疑是不是coredns响应慢或者哪个环节丢包导致。

于是决定从查dns问题作为切入点。

因此,我启动了1个不接入流量的POD,杀死了容器内的nscd缓存组件,并在POD内进行域名解析压测(测试代码),观察到的确存在超过5秒的解析请求。

查看了POD所在node的conntrack的insert_failed指标为0,大概率排除网上流传的”coredns 5秒问题”,我本身也不太怀疑conntrack会有新的问题,毕竟之前优化conntrack并做过压测。

虽说如此,我还是决定绕开NAT直连coredns的POD进行压测,消除一下NAT方面的丢包可能性。

方法很简单,修改POD内/etc/resolv.conf中nameserver配置,直接指向具体的coredns POD IP,测试后仍旧有5秒超时情况,其实5秒是/etc/resolv.conf的默认timeout配置。

接下来怀疑coredns是不是性能有问题,可是官方数据coredns可以提供40K的QPS,而此时单个coredns的QPS才几千,而且直连测试了所有coredns POD,发现都存在超时,难道所有coredns容器性能都不好了?

线下压测coredns

因为之前对Coredns没做过基线性能摸底,所以决定去线下K8S集群做压测。

无论是经过service压测还是直连coredns pod ip压测,其性能表现都与官方数据一致,大概就是40K QPS。

当流量再高时,coredns开始丢包,确认的方式是nsenter进去coredns的network namespace,通过netstat -s 查看udp socket的buffer溢出计数器开始上涨,印证是coredns的收包性能到达瓶颈。

那么,为什么线上coredns几千QPS就开始出现超时呢?显然问题应该与coredns无关,因此当我去线上查看coredns的日志以及nestat时候,的确没有出现任何的慢查询,在prometheus中的监控也可以印证这一点。

复现抓包

既然coredns没有性能问题,那么问题就是网络丢包,导致客户端发出的DNS解析请求没有在5秒内收到应答。

因此我们需要通过抓包来明确掉包点。

首先我在测试POD内,修改resolv.conf的nameserver直接指向某一个coredns POD。

此后,我们需要在两侧同时开启抓包:

  • 在coredns POD所在node上eth0网卡开启抓包,利用tshark抓取来自客户端POD与53端口之间的流量。
  • 在客户端POD所在node上eth0网卡开启抓包,利用tshark抓包客户端POD与53端口之间的流量。

接下来,在测试POD内单线程循环,发起dns同步解析请求,一旦出现慢响应则线程会hung住直到5秒超时。

一旦复现,则停止两侧抓包,利用wireshark工具分析包到底掉在哪个环节。

你必须付费加入我的知识星球,为有效知识付费是对作者最好的回报。

二维码见下方 或者 右侧边栏。