0%

K8S问题排查-业务高并发导致Pod反复重启(续)

问题背景

接上次的问题,一段时间后,环境再次出现harborcalico因为健康检查不过反复重启的问题,并且使用kubectl命令进入Pod也响应非常慢甚至超时。

1
2
[root@node01 ~]# kubectl exec -it -n system node1-59c9475bc6-zkhq5 bash
^

原因分析

反复重启的原因上次已定位,这次上环境简单看还是因为健康检查超时的问题,并且现象也一样,TCP的连接卡在了第一次握手的SYN_SENT阶段。

1
2
3
[root@node01 ~]# netstat -anp|grep 23380
tcp 0 0 127.0.0.1:23380 0.0.0.0:* LISTEN 38914/kubelet
tcp 0 0 127.0.0.1:38983 127.0.0.1:23380 SYN_SENT -

也就是说,除了TCP连接队列的问题,还存在其他问题会导致该现象。先看看上次的参数还在不在:

1
2
3
[root@node01 ~]# cat /etc/sysctl.conf
net.ipv4.tcp_max_syn_backlog = 32768
net.core.somaxconn = 32768

再看下上次修改的参数是否生效:

1
2
3
[root@node01 ~]# ss -lnt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 32768 127.0.0.1:23380 *:*

参数的修改也生效了,那为什么还会卡在SYN_SENT阶段呢?从现有情况,看不出还有什么原因会导致该问题,只能摸索看看。

  1. 在问题节点和非问题节点上分别抓包,看报文交互是否存在什么异常;
  2. 根据参考资料[1],排查是否为相同问题;
  3. 根据参考资料[2],排查是否相同问题;

摸索一番,没发现什么异常。回过头来想想,既然是业务下发大量配置导致的,并且影响是全局的(除了业务Pod自身,其他组件也受到了影响),说明大概率原因还是系统层面存在的性能瓶颈。业务量大的影响除了CPU、一般还有内存、磁盘、连接数等等,与开发人员确认他们的连接还是长连接,那么连接数很大的情况下会受到什么内核参数的影响呢?其中一个就是我们熟知的文件句柄数。

1
2
3
4
5
[root@node01 ~]# lsof -p 45775 | wc -l
17974

[root@node01 ~]# lsof -p 45775|grep "sock"| wc -l
12051

嗯,打开了1w+的文件句柄数并且基本都是sock连接,而我们使用的操作系统默认情况下每个进程的文件句柄数限制为1024,查看确认一下:

1
2
[root@node01 ~]# ulimit  -n
1024

超额使用了这么多,业务Pod竟然没有too many open files错误:

1
2
3
[root@node01 ~]# kubectl logs -n system node1-59c9475bc6-zkhq5
start config
...

临时修改一下:

1
2
3
[root@node01 ~]# ulimit -n 65535
[root@node01 ~]# ulimit -n
65535

再次使用kubectl命令进入业务Pod,响应恢复正常,并且查看连接也不再有卡住的SYN_SENT阶段:

1
2
3
4
5
6
7
8
9
10
11
12
[root@node01 ~]# kubectl exec -it -n system node1-59c9475bc6-zkhq5 bash
[root@node1-59c9475bc6-zkhq5]# exit
[root@node01 ~]# kubectl exec -it -n system node1-59c9475bc6-zkhq5 bash
[root@node1-59c9475bc6-zkhq5]# exit
[root@node01 ~]# kubectl exec -it -n system node1-59c9475bc6-zkhq5 bash
[root@node1-59c9475bc6-zkhq5]# exit

[root@node01 ~]# netstat -anp|grep 23380
tcp 0 0 127.0.0.1:23380 0.0.0.0:* LISTEN 38914/kubelet
tcp 0 0 127.0.0.1:56369 127.0.0.1:23380 TIME_WAIT -
tcp 0 0 127.0.0.1:23380 127.0.0.1:57601 TIME_WAIT -
tcp 0 0 127.0.0.1:23380 127.0.0.1:57479 TIME_WAIT -

解决方案

  1. 业务根据实际情况调整文件句柄数。
  2. 针对业务量大的环境,强烈建议整体做一下操作系统层面的性能优化,否则,不定哪个系统参数就成了性能瓶颈,网上找了个调优案例[3],感兴趣的可以参考。

参考资料

  1. https://blog.csdn.net/pyxllq/article/details/80351827
  2. http://mdba.cn/2015/03/10/tcp-socket文件句柄泄漏
  3. https://www.shuzhiduo.com/A/RnJW7NLyJq/