笔记。 翻译。:Zalando 的首席工程师 Henning Jacobs 多次注意到 Kubernetes 用户在理解活性(和就绪)探针的目的及其正确使用方面存在问题。 因此,他将自己的想法集中在这篇大篇幅的笔记中,最终将成为 K8s 文档的一部分。
健康检查,在 Kubernetes 中称为 活性探针 (即,字面意思是“生存能力测试”-大约翻译。),可能非常危险。 我建议尽可能避免使用它们:唯一的例外是当它们确实有必要并且您完全了解其使用的具体情况和后果时。 本出版物将讨论活性和就绪性检查,还将告诉您在什么情况下 成本 你不应该使用它们。
我的同事 Sandor 最近在 Twitter 上分享了他遇到的最常见错误,包括与使用就绪/活跃探针相关的错误:
配置不正确 livenessProbe
可能会加剧高负载情况(滚雪球式关闭+可能较长的容器/应用程序启动时间)并导致其他负面后果,例如依赖性下降 (也可以看看
一般信息 “不要使用活性探针” 在这种情况下它没有多大帮助,所以让我们看看就绪性和活性检查的用途。
注意:下面的大部分测试最初包含在 Zalando 的内部开发人员文档中。
准备情况和活性检查
Kubernetes 提供了两种重要的机制,称为
Kubernetes 使用 就绪探针了解容器何时准备好接受流量。 如果 Pod 的所有容器都准备就绪,则认为该 Pod 已准备好使用。 该机制的用途之一是控制将哪些 Pod 用作 Kubernetes 服务(尤其是 Ingress)的后端。
活性探针 帮助 Kubernetes 了解何时需要重新启动容器。 例如,这样的检查允许您在应用程序卡在一个地方时拦截死锁。 尽管出现错误,但在此状态下重新启动容器有助于应用程序启动,但也可能导致级联故障(见下文)。
如果您尝试部署未通过活动/就绪检查的应用程序更新,则其部署将因 Kubernetes 等待状态而停止 Ready
来自所有 pod。
例子
这是检查路径的就绪探针的示例 /health
通过 HTTP 使用默认设置 (间隔:10秒, 超时: 1秒, 成功门槛:1, 失败阈值:3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080
建议
- 对于具有 HTTP 端点(REST 等)的微服务 始终定义就绪探针,它检查应用程序 (pod) 是否准备好接受流量。
- 确保就绪探针 涵盖实际 Web 服务器端口的可用性:
- 将端口用于管理目的,称为“admin”或“management”(例如,9090),例如
readinessProbe
,确保端点仅在主 HTTP 端口(如 8080)准备好接受流量*时才返回 OK;*据我所知,Zalando 至少有一个案例没有发生这种情况,即
readinessProbe
我检查了“管理”端口,但由于加载缓存的问题,服务器本身没有开始工作。 - 将就绪探针附加到单独的端口可能会导致主端口的过载不会反映在健康检查中(即服务器上的线程池已满,但健康检查仍然显示一切正常) )。
- 将端口用于管理目的,称为“admin”或“management”(例如,9090),例如
- 确保 就绪探针支持数据库初始化/迁移;
- 实现此目的的最简单方法是仅在初始化完成后才联系 HTTP 服务器(例如,从
飞路 等等。); 也就是说,在数据库迁移完成之前不要启动 Web 服务器,而不是更改运行状况检查状态*。* 您还可以从 pod 外部的 init 容器运行数据库迁移。 我仍然喜欢独立应用程序,即应用程序容器知道如何在无需外部协调的情况下使数据库进入所需状态的应用程序。
- 实现此目的的最简单方法是仅在初始化完成后才联系 HTTP 服务器(例如,从
- 使用
httpGet
通过典型的运行状况检查端点(例如,/health
). - 了解默认检查参数 (
interval: 10s
,timeout: 1s
,successThreshold: 1
,failureThreshold: 3
):- 默认选项意味着 pod 将变成 没有准备好 大约 30 秒后(3 次健全性检查失败)。
- 如果技术堆栈(例如 Java/Spring)允许,请使用单独的“admin”或“management”端口,将运行状况和指标管理与常规流量分开:
- 但不要忘记第 2 点。
- 如有必要,就绪探针可用于预热/加载缓存并返回 503 状态代码,直到容器预热:
- 我还建议您阅读新支票
startupProbe
,出现在1.16版本中 (我们用俄语写过这里 - 大约。 译).
- 我还建议您阅读新支票
注意事项
- 不要依赖外部依赖 (例如数据仓库)运行就绪性/活跃性测试时 - 这可能会导致级联故障:
- 举个例子,我们以一个有 10 个 Pod 的有状态 REST 服务为例,该服务依赖于一个 Postgres 数据库:当检查依赖于与数据库的工作连接时,如果网络/数据库端存在延迟,则所有 10 个 Pod 都可能会失败 - 通常是这样一切的结局都比它可能的更糟;
- 请注意,Spring Data 默认检查数据库连接*;
* 这是 Spring Data Redis 的默认行为(至少是我上次检查的时候),这导致了“灾难性”故障:当 Redis 短时间不可用时,所有 pod 都“崩溃”了。
- 从这个意义上来说,“外部”也可以指同一应用程序的其他 pod,也就是说,理想情况下,检查不应依赖于同一集群的其他 pod 的状态,以防止级联崩溃:
- 对于具有分布式状态的应用程序(例如,pod 中的内存缓存),结果可能会有所不同。
- 不要使用活性探针 对于 pod(例外情况是确实有必要并且您完全了解其使用的具体情况和后果):
- 活性探针可以帮助恢复挂起的容器,但由于您可以完全控制应用程序,因此理想情况下不应发生挂起进程和死锁之类的情况:最好的替代方案是故意使应用程序崩溃并将其恢复到之前的稳定状态;
- 失败的活性探测将导致容器重新启动,从而可能加剧加载相关错误的后果:重新启动容器将导致停机(至少在应用程序启动期间,例如 30 多秒),从而导致新的错误、增加其他集装箱的负载并增加其故障的可能性等;
- 活性检查与外部依赖项相结合是最糟糕的组合,可能会导致级联故障:数据库端的轻微延迟将导致所有容器重新启动!
- 活性和就绪检查参数 一定是不同的:
- 您可以使用具有相同运行状况检查但响应阈值更高的活性探针(
failureThreshold
),例如,分配状态 没有准备好 3次尝试后,并在10次尝试后认为活性探测失败;
- 您可以使用具有相同运行状况检查但响应阈值更高的活性探针(
- 不要使用执行检查,因为它们与导致僵尸进程出现的已知问题相关:
- 详情:参见
Datadog专家的演讲 .
- 详情:参见
总结
- 使用就绪探测来确定 Pod 何时准备好接收流量。
- 仅在真正需要时才使用活性探针。
- 就绪/活跃探针使用不当可能会导致可用性降低和级联故障。
关于该主题的其他材料
-
Kubernetes 文档:配置 Liveness 和 Readiness 探针 ; -
重新审视 Kubernetes 活跃度和就绪度探针:如何避免搬起石头砸自己的脚 ; -
NRE 实验室中断事后分析 (他还谈到了 livenessProbe)。
1-2019-09 更新第 29 号
2-2019-09 更新第 29 号
译者PS
另请阅读我们的博客:
来源: habr.com