一、问题描述
用k8s启动了一个springboot的deloyment资源对象,结果就一直启动不起来。通过kubectl logs 查看,发现springboot处于一直重启状态,且pod也是一直被删除重建。
说明k8s认定springboot这个pod未存活,于是重建重启
二、问题原因
由于deployment.yaml设置了livenessProbe和readinessProbe探针,livenessProbe代表pod是否存活,readinessProbe代表pod是否就绪。
分别对应的是springboot(2.3.6-RELEASE)的/actuator/health/liveness和/actuator/health/readiness接口。
说明livenessProbe调用/actuator/health/liveness接口时判定了springboot未存活,所以一直重复删除pod,新建pod,启动springboot,陷入的循环。
三、问题解决
其实,deployment中的livenessProbe和readinessProbe有很多参数供我们选择参数,如果不设置则采用默认值,而默认值导致我们的业务异常。
- initialDelaySeconds:在初始化容器多少秒后开始第一次就绪探测;
- timeoutSeconds:如果该次就绪探测超过多少秒后还未成功,判定为超时,该次探测失败,Pod不就绪。默认值1,最小值1;
- periodSeconds:如果Pod未就绪,则每隔多少秒周期性的做就绪探测。默认值10,最小值1;
- failureThreshold:如果容器之前探测成功,后续连续几次探测失败,则确定容器未就绪。默认值3,最小值1;
- successThreshold:如果容器之前探测失败,后续连续几次探测成功,则确定容器就绪。默认值1,最小值1。
一般我们springboot项目比较大的话,可能启动时间较慢,当启动时间 > initialDelaySeconds + timeoutSeconds时,则会出现springboot一直重启,deployment一直重建pod的情况
-------------------------------------------------------------------------------------------------------------------------------------
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
failureThreshold: 10
timeoutSeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 10
periodSeconds: 5
===================================================
更新:
进程一直重启另一个原因可能是分配的内存过小:
springboot 进程需要设置最大堆内存,同时Pod内部分配的资源大于等于设置的堆内存大小。也要考虑非堆的内存