【问题标题】:Cannot understand the deadlock scenario in `When should you use a startup probe` of kubernetes?无法理解 kubernetes 的 `When should you use a startup probe` 中的死锁场景?
【发布时间】:2021-01-22 13:27:07
【问题描述】:

在 kubernetes 官方文档中,我正在阅读这个页面(关于 container probes 以及为什么我们应该使用 startup-probe
when-should-you-use-a-startup probe,他们说:

如果您的容器通常在多个initialDelaySeconds + failureThreshold × periodSeconds 中启动,您应该指定一个启动探针来检查与 liveness 探针相同的端点。 periodSeconds 的默认值为 10 秒。然后,您应该将其 failureThreshold 设置为足够高以允许容器启动,而无需更改 liveness 探针的默认值。这有助于防止死锁。

我理解为什么我们需要使用startup probe 的全部内容(我理解为什么我们需要使用startup probe 的原因是:启动探针对于容器需要很长时间才能进入的 Pod 很有用服务。我们知道,如果提供了启动探针,则所有其他探针都将被禁用,直到它成功。因此,如果容器需要更长的时间来启动,那么我们将使用startup probe,这样在容器启动之前,其他两个探针仍然存在禁用)。

但是在这里我没有得到deadlock 的场景,deadlock 在哪里以及为什么会发生?谁能解释他们正在谈论的deadlock 的场景?我们使用startup probe 阻止了哪个deadlock

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    startup probe 设计为仅在容器启动后执行一次。

    Readiness probeliveness Probe 不仅在启动时执行。

    如果启动探测超过了配置的 failureThreshold 而没有成功,容器将被杀死并重新启动,受 pod 的 restartPolicy 约束,这种行为类似于 liveness 探测。

    负载均衡器可以使用就绪探测来确定何时可以发送流量。

    启动探针用例

    使用startup probe 的示例原因是:

    您的应用程序启动了很长时间。您可以为readiness probeliveness probe 增加delays,但您不知道您的容器何时准备就绪,因为这些探测未在delay 时间内执行。

    所以startup probe 通常与readinesliveness 探针一起使用。它一直执行到您的容器准备就绪(直到您的startup probe 返回Success 状态),因此您不再需要延迟。

    外部依赖

    假设您的应用程序启动 1-3 分钟(它可能取决于外部 API、资源、慢速网络等)。您可以将delays 设置为 190 秒,但如果您的容器在 60 秒后准备就绪,您可能会浪费至少 2 分钟。为了解决这个问题,设计了startup probe

    第一次初始化

    有时,您必须处理在首次初始化时可能需要额外启动时间的遗留应用程序。在这种情况下,在不影响对引发这种探测的死锁的快速响应的情况下设置活跃度探测参数可能会很棘手。诀窍是使用相同的命令设置启动探测,HTTP 或 TCP 检查,failureThreshold * periodSeconds 足够长以涵盖最坏情况的启动时间。

    你的问题

    死锁是一种情况,当你的容器没有准备好但是liveness probe正在执行并且它超过failure treshold,因为延迟时间太短了。在这种情况下,您的容器会不断重启。为防止这种情况发生,您应该使用 startup probe 并将阈值设置得足够高。

    【讨论】:

    • 我现在明白了,容器在启动之前一直在重新启动,这就是为什么这里会发生死锁,谢谢。
    【解决方案2】:

    我现在完全清楚我的问题了。所以我想解释一下我理解的完整场景(希望它将来会帮助其他人)。 @Daniel 的答案是正确的,但我只是想更全面地解释一下。

    条款解释:

    1. initialDelaySeconds:容器启动后的秒数,然后再调度探测,这意味着在此之后,定义的探测将调度。
    2. failureThreshold:在 liveness 探针重新启动容器之前允许探针失败的次数(或者在 readiness 探针将 pod 标记为不可用的情况下)
    3. periodSeconds:这意味着在每个periodSeconds 中,kubelet 都会执行预定的探测。
    4. initialDelaySeconds + failureThreshold × periodSeconds:总时间,之后调度的probe会根据它们的特性采取行动(liveness probe会重新启动容器,或者在readiness probe的情况下会将pod标记为不可用)

    来自@Daniel 的评论,还请记住,所有探测器都已将failureThresholdperiodSeconds 分开。因此,对于liveness probe,这些值可能很小,可以在容器无法正常工作的情况下尽快杀死容器,对于starup probe,这些值可以更高,以便等待足够长的时间来启动。

    死锁是如何发生的

    现在,如果未使用 startup probe 并且容器的启动时间比总 (initialDelaySeconds + failureThreshold × periodSeconds) 时间长,那么在容器启动之前,liveness probe 将通过 kubelet 重新启动容器,只要 @ 987654333@ 时间过去了,因为如果 liveness probe 失败,kubelet 会杀死容器,容器受其重启策略约束。

    在重启容器时会再次发生同样的情况,并且会一次又一次地发生,并且每次都无法启动容器。这里发生了死锁。

    所以发生了死锁,因为容器的启动时间超过了initialDelaySeconds + failureThreshold × periodSeconds,而我们在这里没有使用startup probe

    防止死锁

    现在为了防止死锁,我们可以做两件事:

    1. 我们可以给高liveness interval,但由于容器可以花费的时间不是固定的,这就是为什么这种方法不是更好的方法。

    2. 我们可以使用startup probe,我们知道,如果提供了启动探针,则所有其他探针都将被禁用,直到它成功为止。所以如果我们使用startup probe,我们就不需要考虑之前发生的死锁了。

    现在只剩下另一件事了,那就是我们需要给高 failureThreshold 因为如果容器的启动时间超过 initialDelaySeconds + failureThreshold × periodSeconds 时间,startup probe 也会失败(这里需要明确一点: initialDelaySeconds + failureThreshold × periodSeconds是通用公式,对所有探针分别计算)。所以我们还需要在使用startup probe时设置高failureThreshold。这样就可以彻底解决deadlock的问题,也可以保证容器有足够的时间启动。

    【讨论】:

    • So the deadlock is happening because the container was taking longer than initialDelaySeconds + failureThreshold × periodSeconds time to start up and we did not used startup probe here. 没错。作为一种解决方案,您可以将initialDelaySeconds 增加几次,但即使容器已准备好使用,您的容器也要等到initialDelaySeconds 完成后才能使用。所以这是用starup probe替换延迟时间的原因@
    • 还请记住,所有探测器都已将failureThresholdperiodSeconds 分开。因此对于liveness probe,这些值可能很小,可以在容器无法正常工作时尽快杀死容器,对于启动探测值可以更高,以等待足够长的时间来启动
    • @DanielHornik 是的,我也理解那部分,谢谢提及
    猜你喜欢
    • 1970-01-01
    • 2020-02-20
    • 2020-05-02
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多