Pod 健康检查失败

  • Kubernetes 健康检查包含就绪检查(readinessProbe)和存活检查(livenessProbe)
  • pod 如果就绪检查失败会将此 pod ip 从 service 中摘除,通过 service 访问,流量将不会被转发给就绪检查失败的 pod
  • pod 如果存活检查失败,kubelet 将会杀死容器并尝试重启

健康检查失败的可能原因有多种,除了业务程序BUG导致不能响应健康检查导致 unhealthy,还能有有其它原因,下面我们来逐个排查。

健康检查配置不合理

initialDelaySeconds 太短,容器启动慢,导致容器还没完全启动就开始探测,如果 successThreshold 是默认值 1,检查失败一次就会被 kill,然后 pod 一直这样被 kill 重启。

节点负载过高

cpu 占用高(比如跑满)会导致进程无法正常发包收包,通常会 timeout,导致 kubelet 认为 pod 不健康。参考本书 处理实践: 高负载 一节。

容器进程被木马进程杀死

参考本书 处理实践: 使用 systemtap 定位疑难杂症 进一步定位。

容器内进程端口监听挂掉

使用 netstat -tunlp 检查端口监听是否还在,如果不在了,抓包可以看到会直接 reset 掉健康检查探测的连接:

20:15:17.890996 IP 172.16.2.1.38074 > 172.16.2.23.8888: Flags [S], seq 96880261, win 14600, options [mss 1424,nop,nop,sackOK,nop,wscale 7], length 0
20:15:17.891021 IP 172.16.2.23.8888 > 172.16.2.1.38074: Flags [R.], seq 0, ack 96880262, win 0, length 0
20:15:17.906744 IP 10.0.0.16.54132 > 172.16.2.23.8888: Flags [S], seq 1207014342, win 14600, options [mss 1424,nop,nop,sackOK,nop,wscale 7], length 0
20:15:17.906766 IP 172.16.2.23.8888 > 10.0.0.16.54132: Flags [R.], seq 0, ack 1207014343, win 0, length 0

连接异常,从而健康检查失败。发生这种情况的原因可能在一个节点上启动了多个使用 hostNetwork 监听相同宿主机端口的 Pod,只会有一个 Pod 监听成功,但监听失败的 Pod 的业务逻辑允许了监听失败,并没有退出,Pod 又配了健康检查,kubelet 就会给 Pod 发送健康检查探测报文,但 Pod 由于没有监听所以就会健康检查失败。

SYN backlog 设置过小

SYN backlog 大小即 SYN 队列大小,如果短时间内新建连接比较多,而 SYN backlog 设置太小,就会导致新建连接失败,通过 netstat -s | grep TCPBacklogDrop 可以看到有多少是因为 backlog 满了导致丢弃的新连接。

如果确认是 backlog 满了导致的丢包,建议调高 backlog 的值,内核参数为 net.ipv4.tcp_max_syn_backlog

「真诚赞赏,手留余香」

roc

请我喝杯咖啡?

使用微信扫描二维码完成支付