kubernetes pod探针
Pod探针
Kubernetes 对 Pod 的健康状态可以通过三种探针来检查: LivenessProbe 、ReadinessProbe、startupProbe
● readinessProbe
● livenessProbe
● startupProbe(这个1.16版本增加的)
LivenessProbe探针
用于判断容器是否存活(Running状态) ,如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含LivenesspProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是Success。
ReadinessProbe探针
有时候,应用会暂时性地无法为请求提供服务。 例如,应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用,也不想给它发送请求。 Kubernetes 提供了就绪探针来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。
就绪探针在容器的整个生命周期中保持运行状态。
StartupProbe探针介绍
k8s 在1.16版本后增加startupProbe探针,主要解决在复杂的程序中readinessProbe、livenessProbe探针无法更好的判断程序是否启动、是否存活。进而引入startupProbe探针为readinessProbe、livenessProbe探针服务。
startupProbe探针与另两种区别
如果三个探针同时存在,先执行startupProbe探针,其他两个探针将会被暂时禁用,直到pod满足startupProbe探针配置的条件,其他2个探针启动,如果不满足按照规则重启容器
另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而startupProbe探针只是在容器启动后按照配置满足一次后,不再进行后续的探测。
检测方式及参数配置
方式 | 描述 |
ExecAction | 在容器内部执行一个命令,如果该命令的返回码为0,则表明 容器健康。 |
TCPSocketAction | 通过容器的IP地址和端口号执行TCP检查,如果能够建立 TCP连接,则表明容器健康。 |
HTTPGetAction | 通过容器的IP地址、端口号及路径调用HTTP Get方法, 如果响应的状态码大于等于200且小于400,则 |
pod健康检查最佳实践
延迟时间
对于Livness的配置,需要重点理解参数“延迟时间”,其作用是帮助健康检查探针在合适的时候去探测业务容器的状态。如果Livness健康检查在不合适的时候去探测(延迟时间过短),会导致不断重启这一严重后果。
例如,一个Java应用启动可能需要耗时2分钟,如果全部按照默认配置,即延迟时间为10秒,检查周期为30秒,失败阈值为3,该应用将永远不可能启动成功。因为在上述设置中,Livness探针的三次健康检查全部是在应用启动完毕之前完成的,而应用启动完毕之前进行健康探测,持续失败就是预期中的结果。所以,该应用必然会不断重启。
因此,当初次部署应用时,如果无法确定应用的启动时间,可以尽量将延迟时间调长一点(例如5分钟),等应用成功启动后,再根据业务日志确定大致的启动耗时来修正延迟时间。需要注意的是,延迟时间过长也存在弊端,因为可能会让整个发布时间过长。
TCP与HTTP方式的选择
Liveness另一个容易踩坑的点是检查方式,用户需要为Readiness与Liveness配置不同的检查方式。但是,许多用户为了省事,将Readiness与Liveness设置成相同的检查,其实这是非常危险的行为。因为Liveness与Readiness是两种完全不同的探针,有着完全不同的作用。有时候业务由于流量拥塞导致不可用,只需摘除当前实例的流量,无需重启容器。当前请求被正常处理完成后,就可以重新负载流量并接收请求。但是,如果此时重启容器,可能会产生以下影响:当前已有请求无法被顺利处理。
● 由于当前实例重启,可能会导致更长的时间无法负载流量,甚至出现雪崩。
例如,对于Java应用,Spring Boot框架提供了内置的健康检查。该健康检查会检测多个组件的情况,例如与Redis、Nacos等组件连接与心跳是否正常,并判断是否需要重启应用。由于网络抖动以及相关组件服务的可用性无法完全确定,这类异常无法成为当前应用是否需要重启的判断依据。
因此,为了减少因下游链路的抖动造成预期外的实例重启,必须区分Liveness与Readiness。如果不方便单独实现一个接口来检查应用自身的情况,可以通过Liveness采用TCP、Readiness采用HTTP的方式探测。重启这一操作需要谨慎对待,因此检测容错率更高的TCP方式更适合Liveness。HTTP方式的检测更容易反映业务的真实处理情况,更适合Readiness这一处理流量的检测。
失败阈值与成功阈值
对于Livenss而言,其实只有一个动作,即失败重启。因此,成功阈值固定为1,且不可修改(由于成功没有显式动作,所以成功阈值大于1也没有意义)。而失败阈值默认为3,即连续失败三次,会认为真正失败,并开始重启容器。
对于Readiness而言,其实有两种动作,成功则接入流量,失败则切出流量。因此,为保证可用性,成功阈值与失败阈值都推荐设置为1,即当出现检测失败时立即切出流量,从而尽可能短时间内避免流量有损,而当检测成功(即应用已经做好接收流量的准备)后立即切入流量。但是,快速切流可能导致剩余实例平均网络负载进一步增加,因此建议配合指标弹性一起使用。
● 对于较旧的(≤v1.15)Kubernetes 集群,使用具有初始延迟的 readiness 探针来处理容器启动阶段。
● 对于较新的(≥v1.16)Kubernetes 集群,如果是具有不可预测或可变启动时间的应用程序应使用 startup 探针。startup 探针与 readiness 和 liveness 探针共享相同的 endpoint(例如 /healthz),但能将 failureThreshold 设置得比其他探针更高,以拥有更长的启动时间,相对于 liveness 和 readiness 而言,设置的失败时间会更合理。
● 如果 readiness 探针不用于其他信号目的,readiness 和 liveness 探针可以共享相同的 endpoint,但如果只有一个 Pod(也就是使用 VPA)时,设置 readiness 探针来解决启动行为,使用 liveness 探针来确定运行状况。这种情况下,标记 Pod 不健康意味着停机时间。
● readiness 检查可以用各种方式来发出系统故障的信号。例如,当应用程序失去与数据库的连接时,可以使用 readiness 探针暂时阻止新请求并允许系统重新连接。它还可以将繁忙的 Pod 标记为未准备,将工作负载平衡到其他 Pod。
如果 initialDelaySeconds 设置过大(无法预测项目启动时间,粗略估计100-200秒甚至更长,那我直接设置300秒),此时每次发布,无论项目启动快慢,我都需要等到5分钟以后才能得到 Pod状态的反馈,时间过长我无法容忍;按上边的 timeoutSeconds 和 periodSeconds 设置,一次失败检测周期 10秒,并提供了 failureThreshold 5次失败机会,这时候把 failureThreshold 改为 10次失败机会,60+10*10=160s 似乎接近覆盖项目启动时间,可以减少无限重启的概率,但是如果我的项目真的存在问题,在启动成功后,后续每10秒一个探测中,当项目已停止我需要 10*10=100s 左右才能被发现,然后重启,这种反射弧在线上环境是无法被容忍的;
参考
K8S 三种探针 readinessProbe、livenessProbe和startupProbe-CSDN博客
掌握SpringBoot-2.3的容器探针:深入篇-阿里云开发者社区掌握SpringBoot-2.3的容器探针:实战篇_springboot applicationavailability-CSDN博客
原文地址:https://blog.csdn.net/huchao_lingo/article/details/142420768
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!