You need to enable JavaScript to run this app.
导航
Pod 健康检查失败
最近更新时间:2024.01.24 10:57:38首次发布时间:2023.09.05 19:43:48

问题描述

容器服务及群中的健康检查主要包括:就绪检查(readinessProbe)存活检查(livenessProbe)

  • 如果就绪检查失败,系统会将 Pod 的 IP 地址 从 Service 中去除。当通过 Service 访问业务时,流量将不会被转发给就绪检查失败的 Pod。
  • 如果存活检查失败,kubelet 将会停止容器并尝试重启。

导致 Pod 健康检查失败的原因很多,除了业务 BUG 导致 Pod 不能响应健康检查探针,造成 Pod 状态为unhealthy外,还可能与其他原因有关。

原因分析

Pod 健康检查失败,可能的原因如下:

  • 健康检查配置不合理
  • 节点负载过高
  • 容器内进程端口监听故障
  • SYN backlog 设置过小

解决方法

健康检查配置不合理

健康检查的配置不合理,会导致 Pod 健康检测失败。例如:初始等待时间initialDelaySecondsp配置的太短,同时容器启动慢,导致容器还没完全启动就开始探测。此时,如果失败阈值failureThreshold设置为 1,则 Pod 健康检查失败一次就会被停止,那么 Pod 将会持续被停止并重启。

节点负载过高

节点高负载将会导致进程无法获得足够运行所需的 CPU 时间片,通常表现为网络 Timeout、健康检查失败或服务不可用。

您可以使用top命令来确定 load average 值,也可以通过 Cpu(s)、Mem、%CPU 及 %MEM 列的数据获取哪些进程正在占用大多数资源。操作步骤如下:

  1. 登录节点,使用top命令查看节点当前负载。如果 load 小于 CPU 数量,则属于低负载,如果大于 CPU 数量 2~3 倍,就属于高负载。返回结果示例如下。
top - 19:42:06 up 23:59,  2 users,  load average: 34.64, 35.80, 35.76
Tasks: 679 total,   1 running, 678 sleeping,   0 stopped,   0 zombie
Cpu(s): 15.6%us,  1.7%sy,  0.0%ni, 74.7%id,  7.9%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  32865032k total, 30989168k used,  1875864k free,   370748k buffers
Swap:  8388604k total,     5440k used,  8383164k free,  7982424k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 9783 mysql     20   0 17.3g  16g 8104 S 186.9 52.3   3752:33 mysqld
 6540 nginx     20   0 1306m  40m 7884 S  3.3  0.1   0:02.46 php-fpm
 5553 nginx     20   0 1300m  36m 9568 S  3.0  0.1   0:21.58 php-fpm
 5722 nginx     20   0 1310m  45m 8552 S  3.0  0.1   0:17.25 php-fpm
 5920 nginx     20   0 1302m  36m 8208 S  3.0  0.1   0:14.23 php-fpm
 6432 nginx     20   0 1310m  45m 8420 S  3.0  0.1   0:05.86 php-fpm
 5285 nginx     20   0 1302m  38m 9696 S  2.7  0.1   0:23.41 php-fpm
  1. 如果 load 高,但 CPU 利用率不高,通常是因为同时运行的进程/线程过多导致的。
    • 使用如下命令,查看当前的 PID 数量。如果 PID 数量过多,可以大概浏览下都有哪些进程,如果有大量重复启动命令的进程,就可能是这个进程对应程序的 BUG 导致。
      ps -eLf | wc -l
      
      
    • 您也可以使用以下命令统计线程数排名。线程数量较多的进程可能发生了线程泄漏,会导致 PID 耗尽。
      printf "NUM\tPID\tCOMMAND\n" && ps -eLf | awk '{$1=null;$3=null;$4=null;$5=null;$6=null;$7=null;$8=null;$9=null;print}' | sort |uniq -c |sort -rn | head -10
      
  2. top命令的返回结果中,您可查看 CPU 核的wa值,该值表示 CPU 空闲且磁盘 IO 阻塞的时间占比。按下键盘上的 1 键,允许您查看每个核的wa值,如下所示。
top - 19:42:08 up 23:59,  2 users,  load average: 34.64, 35.80, 35.76
Tasks: 679 total,   1 running, 678 sleeping,   0 stopped,   0 zombie
Cpu0  : 29.5%us,  3.7%sy,  0.0%ni, 48.7%id, 17.9%wa,  0.0%hi,  0.1%si,  0.0%st
Cpu1  : 29.3%us,  3.7%sy,  0.0%ni, 48.9%id, 17.9%wa,  0.0%hi,  0.1%si,  0.0%st
Cpu2  : 26.1%us,  3.1%sy,  0.0%ni, 64.4%id,  6.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu3  : 25.9%us,  3.1%sy,  0.0%ni, 65.5%id,  5.4%wa,  0.0%hi,  0.1%si,  0.0%st
Cpu4  : 24.9%us,  3.0%sy,  0.0%ni, 66.8%id,  5.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu5  : 24.9%us,  2.9%sy,  0.0%ni, 67.0%id,  4.8%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu6  : 24.2%us,  2.7%sy,  0.0%ni, 68.3%id,  4.5%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu7  : 24.3%us,  2.6%sy,  0.0%ni, 68.5%id,  4.2%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu8  : 23.8%us,  2.6%sy,  0.0%ni, 69.2%id,  4.1%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu9  : 23.9%us,  2.5%sy,  0.0%ni, 69.3%id,  4.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu10 : 23.3%us,  2.4%sy,  0.0%ni, 68.7%id,  5.6%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu11 : 23.3%us,  2.4%sy,  0.0%ni, 69.2%id,  5.1%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu12 : 21.8%us,  2.4%sy,  0.0%ni, 60.2%id, 15.5%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu13 : 21.9%us,  2.4%sy,  0.0%ni, 60.6%id, 15.2%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu14 : 21.4%us,  2.3%sy,  0.0%ni, 72.6%id,  3.7%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu15 : 21.5%us,  2.2%sy,  0.0%ni, 73.2%id,  3.1%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu16 : 21.2%us,  2.2%sy,  0.0%ni, 73.6%id,  3.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu17 : 21.2%us,  2.1%sy,  0.0%ni, 73.8%id,  2.8%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu18 : 20.9%us,  2.1%sy,  0.0%ni, 74.1%id,  2.9%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu19 : 21.0%us,  2.1%sy,  0.0%ni, 74.4%id,  2.5%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu20 : 20.7%us,  2.0%sy,  0.0%ni, 73.8%id,  3.4%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu21 : 20.8%us,  2.0%sy,  0.0%ni, 73.9%id,  3.2%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu22 : 20.8%us,  2.0%sy,  0.0%ni, 74.4%id,  2.8%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu23 : 20.8%us,  1.9%sy,  0.0%ni, 74.4%id,  2.8%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32865032k total, 30209248k used,  2655784k free,   370748k buffers
Swap:  8388604k total,     5440k used,  8383164k free,  7986552k cached

说明

wa值通常应该为 0%,如果经常浮动在 1% 之上,说明存储设备的速度无法跟上 CPU 的处理速度。

  1. 使用atop命令 ,查看当前磁盘 IO 状态。本例中的磁盘 vda 显示 busy 100% ,表示已达到严重性能瓶颈。
PRC | sys    0.61s  | user   0.73s |  #proc    282 |  #trun      1 | #tslpi   872  | #tslpu   103 |  #zombie    0 |  #exit     92 |
CPU | sys       6%  | user      7% |  irq       0% |  idle   1589% | wait      0%  | steal     0% |  guest     0% |  curf 2.39GHz |
CPL | avg1    0.10  | avg5    0.10 |  avg15   0.08 |               | csw    79864  | intr   51369 |               |  numcpu    16 |
MEM | tot    62.4G  | free   44.1G |  cache  15.8G |  dirty   0.2M | buff  709.1M  | slab  909.4M |  shrss   0.0M |  numnode    1 |
SWP | tot     0.0M  | free    0.0M |  swcac   0.0M |               |               |              |  vmcom   4.5G |  vmlim  31.2G |
NUM | tot    62.4G  | free   44.1G |  file   16.5G |  numanode0000 | activ   2.0G  | inact  15.2G |  slab  909.4M |  frag      0% |
PSI | cpusome   0%  | memsome   0% |  memfull   0% |  iosome    0% | iofull    0%  | cs     1/3/8 |  ms     0/0/0 |  is     0/0/0 |
DSK |          vda  | busy    100% |  read       0 |  write     17 | KiB/w      7  | MBr/s    0.0 |  MBw/s    2.8 |  avio 0.18 ms |
DSK |          vdb  | busy      0% |  read       0 |  write     13 | KiB/w      6  | MBr/s    0.0 |  MBw/s    0.0 |  avio 0.23 ms |
NET | transport     | tcpi    3252 |  tcpo    9626 |  udpi       1 | udpo       1  | tcpao     19 |  tcppo     15 |  tcprs      0 |
NET | network       | ipi     3727 |  ipo     9892 |  ipfrw    221 | deliv   3253  |              |  icmpi      0 |  icmpo      0 |
NET | eth0    ----  | pcki    3513 |  pcko    9656 |  sp    0 Mbps | si  311 Kbps  | so 1339 Kbps |  erri       0 |  erro       0 |

    PID  SYSCPU  USRCPU  RDELAY   VGROW   RGROW   RDDSK   WRDSK  RUID      EUID      ST  EXC   THR  S  CPUNR    CPU  CMD        1/5
   2693   0.06s   0.18s   0.05s      0B  760.0K      0B      0B  root      root      --    -    29  S     14     2%  php-fpm
  69735   0.11s   0.12s   0.01s      0B      0B      0B      0B  root      root      --    -     1  R      5     2%  php-fpm
  63223   0.08s   0.04s   0.00s      0B      0B      0B      0B  root      root      --    -     1  S      2     1%  php-fpm
   2464   0.03s   0.06s   0.06s      0B  264.0K      0B   12.0K  root      root      --    -    27  S     13     1%  php-fpm
3064644   0.02s   0.04s   0.00s      0B      0B      0B      0B  root      root      --    -    21  S     14     1%  php-fpm
3622214   0.03s   0.02s   0.00s   92.0K      0B      0B   28.0K  root      root      --    -     1  S     15     1%  php-fpm
  55040   0.04s   0.00s   0.00s      0B      0B      0B      0B  root      root      --    -     1  I      6     0%  php-fpm
3064483   0.01s   0.02s   0.00s      0B   -0.1M      0B      0B  root      root      --    -    13  S     13     0%  php-fpm
   1043   0.02s   0.01s   0.01s      0B      0B      0B      0B  unscd     unscd     --    -     1  S      1     0%  php-fpm
  59090   0.03s   0.00s   0.00s      0B      0B      0B      0B  root      root      --    -     1  I      2     0%  php-fpm
3034537   0.01s   0.01s   0.00s      0B      0B      0B      0B  root      root      --    -    27  S      4     0%  php-fpm
   6331   0.01s   0.01s   0.00s      0B      0B      0B      0B  root      root      --    -    22  S     13     0%  php-fpm

容器内进程端口监听故障

使用netstat -tunlp命令检查容器内的监听端口是否正常。如果不正常,健康检查将会失败。示例如下:

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