“k8s 1.16 版本后引入了启动探针(StartupProb),来应对某些应用程序启动慢的问题。这弥补了存活探针(LivenessProb)在这部分的不足。”
这句话要怎么理解呢?启动探针和存活探针的探针参数都是一样的(例如都有 initialDelaySeconds、periodSeconds 等),那为什么我们还需要启动探针呢?直接用存活探针不行吗?
这是由于它们的核心设计目标和行为逻辑存在本质差异,导致存活探针无法完全替代启动探针的配置。
启动探针应对应用程序启动慢问题
假设一个 Java 应用程序的启动需要 2 分钟,此时启动探针可做如下配置:
startupProbe:
httpGet:
path: /health
port: 8080
successThreshold: 1
failureThreshold: 30 # 允许最多 30 次失败
periodSeconds: 10 # 每 10 秒探测一次 → 总容忍时间 = 30×10 = 300 秒(5 分钟)
可见,应用程序只要在 5 分钟的总容忍时间内启动了,则容器不会重启。
为什么不能通过调大存活探针参数模拟启动探针?
聪明的小伙伴可能想到了通过调大存活探针的初始化时间(initialDelaySeconds)来应对应用程序启动慢的问题,比如这样:
livenessProbe:
initialDelaySeconds: 120 # 等待 2 分钟
periodSeconds: 10
successThreshold: 1
failureThreshold: 3 # 总容忍时间 = 120 + 10×3 = 150 秒(2分半)
但是这样会有一个问题:如果应用程序因资源竞争、依赖延迟等原因导致启动时间偶尔超过 3 分钟,存活探针会立即失败并重启容器。可能导致容器进入不断重启的死循环。
那又有聪明的小伙伴这样想了,我把 initialDelaySeconds 调到 600 秒,这样总不怕了吧!
livenessProbe:
initialDelaySeconds: 600 # 等待 10 分钟
periodSeconds: 10
successThreshold: 1
failureThreshold: 3 # 总容忍时间 = 600 + 10×3 = 630 秒(10分半)
是的,这样一来容器是启动成功了。可是如果本来只需要等待 2 分钟就能启动成功了,现在却要硬生生等 10 分钟?这合理吗?
那,我维持 initialDelaySeconds 不变,和启动探针一样,把 failureThreshold 调大!
livenessProbe:
initialDelaySeconds: 120 # 等待 2 分钟
periodSeconds: 10
successThreshold: 1
failureThreshold: 30 # 总容忍时间 = 120 + 10×30 = 420 秒(6分钟)
O(∩_∩)O哈哈,这下总可以了吧~
但这里就忽略了一件事:存活探针的生命周期是贯穿整个容器生命周期的。这意味着,只要容器还在,存活探针就一直在工作。而上面设置了 failureThreshold 为 30,这意味着如果容器内的应用程序出现了问题,那得失败整整 30 次,容器才被认为是不健康的,才会去重启!这会导致运行时故障响应延迟(直接影响服务可用性)。
因此,这种方案也不可取。
设计目的不同(职责分离)
-
启动探针:容忍启动慢,为应用争取初始化时间。专注解决「启动阶段」的不确定性,参数可激进(如 periodSeconds=1, failureThreshold=30)。生命周期仅为启动阶段,不影响运行阶段健康检查的效率。
-
存活探针:快速修复运行时故障,保障服务高可用性。专注解决「运行时」的稳定性,参数需保守(如 periodSeconds=10, failureThreshold=3)。生命周期为整个容器运行期间,会影响运行阶段健康检查的效率。
若混用参数,会导致两者都无法高效完成自身职责。
参考方案
startupProbe:
httpGet:
path: /health/startup
port: 8080
failureThreshold: 30 # 允许最多 30 次失败
periodSeconds: 10 # 总容忍时间 = 30×10 = 300 秒(5 分钟)
livenessProbe:
httpGet:
path: /health/runtime
port: 8080
initialDelaySeconds: 0 # 启动探针成功后立即生效
periodSeconds: 5 # 运行时每 5 秒检测一次
failureThreshold: 3 # 连续失败 3 次后重启(15 秒内)
协作流程:
- 启动阶段:
- 启动探针每 10 秒检测一次,最多容忍 5 分钟。
- 存活探针被屏蔽,不会执行。
- 启动成功后:
- 启动探针退出,存活探针接管,每 5 秒检测一次。
- 若运行时健康检查失败,15 秒内触发容器重启。
- 启动失败:
- 启动探针在 5 分钟内未成功,触发容器重启。