最近在调整 resources.limits.cpu 的时候,导致了该 Pod 不断重启的情况出现,此种情况之前从来没有发生过。
通过日志,发现 Pod 往往还没有完全启动起来,就被 K8s 杀掉再次启动了。
打开 Pod 对应的 YAML 文件,发现该 Pod 在容器内配置了 livenessProbe(存活探针),如下:
通过上边的 livenessProbe.initialDelaySeconds 参数,K8s 会在 Pod 启动后延时 30 秒后再对该 Pod 进行存活检查。
通过 kubectl logs 命令查看刚刚启动的 Pod ,发现该 Pod 容器内的 springboot 启动的非常慢,而恰恰 livenessProbe.httpGet.path 指定的 /actuator/info 是该 springboot 项目中提供的一个接口,如果 springboot 在 30秒 内没有启起来,那 /actuator/info 肯定是访问不通的,也就造成存活探测失败,最终导致 K8s 重启该 Pod。
重启的原因找到了,但是这是什么原因造成的呢?
之前从来没有出现过这个问题,只是最近调整了 resources.limits.cpu,才出现了这个问题。会不会和这次调整有关系呢?
带着这个疑问,又回头看了下 YAML 文件的相关配置,如下:
resources.limits.cpu 设置为 200m,也是 200毫核,1/5核,会不会太少了点儿呢?
把 resources.limits.cpu 调整到 500m,也是 500毫核,1/2核,重启再试试 …
果然,这次启动要快速顺畅得多,30秒内 springboot 完全启起来了,存活检查也顺利通过了….
到这里,看似问题已经圆满解决了。但对于我来说,真正的原因并未找到!!!
继续深入 …
打开 SkyWalking ,我发现:Pod 刚刚启动的时候,CPU 使用率会一下子达到 resources.limits.cpu 设定的值,然后,随着服务启动完成,CPU 使用率就会降下来,如下:
通过上边的信息,我得出的结论是:Pod 在启动的时候会将可利用的 CPU 资源都利用上(也就是通过 resources.limits.cpu 来设置的 CPU 最大使用量),来完成服务的启动。启动完成后,根据实际的情况,CPU 利用率会降下来,达到一个稳定的状态。当 resources.limits.cpu 设置过小的时候,也就是说 Pod 在启动的过程中能得到的最大 CPU 资源也会比较少。既然可使用的 CPU 资源减少了,那启动必然也就慢了,当启动的时间远远超过了 livenessProbe 设置的 initialDelaySeconds(从Pod启动开始算延时多久进行首次探测)时间,由于 springboot 还未启动完成,就开始访问 /actuator/info 接口进行存活探测,当然也就不会成功,这样就造成了最后的悲剧:Pod 不断重启,