深入理解 Kubernetes 探针:Liveness, Readiness 与 Startup
文章目录
在 Kubernetes 的世界里,自动化是核心之一。为了实现真正可靠的自动化,系统不仅需要能够启动容器,还必须深刻理解容器的内部状态:它是否正在运行?是否已准备好处理请求?是否已经陷入僵局?这正是 Kubernetes 探针(Probe)发挥作用的地方。
本文严格遵循 Kubernetes 官方文档的核心概念,深入探讨三种关键的探针:livenessProbe, readinessProbe, 和 startupProbe。
探针是什么?
探针是由节点上的 kubelet 对容器周期性执行的诊断。kubelet 通过调用容器中实现的 Handler 来执行检查。Kubernetes 支持三种主要的检查机制:
exec: 在容器内执行指定命令。如果命令退出时返回码为 0,则认为诊断成功。httpGet: 对容器的 IP 地址和指定端口及路径执行 HTTP GET 请求。如果响应的状态码在 200-399 之间,则诊断成功。此 Handler 还支持通过httpHeaders字段设置自定义请求头。tcpSocket: 对容器的 IP 地址上的指定端口进行 TCP 检查。如果端口打开,则诊断成功。gRPC: (Kubernetes v1.27+ 稳定) 对容器暴露的 gRPC 服务执行健康检查。如果服务的状态是SERVING,则诊断成功。这对于基于 gRPC 的现代微服务架构特别有用。
对于每种探针,你都可以配置一些共同的参数来控制其行为:
initialDelaySeconds: 容器启动后,第一次探测前要等待的秒数。periodSeconds: 执行探测的频率(间隔秒数)。默认为 10 秒,最小值为 1。timeoutSeconds: 探测超时的秒数。默认为 1 秒,最小值为 1。successThreshold: 探测失败后,被重新视为成功的最小连续成功次数。默认为 1。对于livenessProbe和startupProbe,此值必须为 1。failureThreshold: 探测成功后,被视为失败的最小连续失败次数。默认为 3。
存活探针 (Liveness Probe)
livenessProbe 用于判断容器是否仍在运行。
更准确地说,它用于处理那些进程依然存在,但已无法正常响应的“僵死”状态(Deadlock)。
当 livenessProbe 探测失败时,kubelet 会杀死该容器,并根据其 restartPolicy(重启策略)来决定是否重启它。
如果一个容器不包含 livenessProbe,那么 kubelet 会默认其 livenessProbe 总是返回 Success。
使用场景
存活探针是修复僵死应用的强大工具。如果你的应用有可能因为内部错误(例如死锁)而夯住,但进程本身不崩溃,livenessProbe 可以通过重启容器来帮助应用恢复。
示例配置
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod-example
spec:
containers:
- name: my-app
image: my-app-image
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
注意:livenessProbe 的检查逻辑应尽可能简单,并且不应依赖外部系统。如果探针因为外部数据库或服务的故障而失败,可能会导致健康的容器被不断重启,引发“级联失败”。
优雅终止与 terminationGracePeriodSeconds:当 livenessProbe 失败导致容器被终止时,Kubernetes 会先发送 TERM 信号让应用优雅退出。应用必须在 terminationGracePeriodSeconds(在 Pod Spec 中定义,默认为 30 秒)内完成清理并退出。否则,将被 KILL 信号强制终止。因此,一个健壮的应用不仅要实现健康检查,还应该正确处理 TERM 信号,以配合探针机制实现真正的优雅自愈。
就绪探针 (Readiness Probe)
readinessProbe 用于判断容器是否准备好接收服务请求。
一个 Pod 启动后,其容器内的应用可能需要一段时间来加载配置、预热缓存或建立与下游服务的连接。在此期间,虽然进程已经启动(livenessProbe 可能成功),但应用尚未完全准备好处理流量。
当 readinessProbe 探测失败时,Kubernetes 的 Endpoints 控制器会从所有匹配该 Pod 的 Service 的 Endpoints 列表中移除该 Pod 的 IP 地址。 这意味着新的流量不会再被路由到这个未就绪的 Pod。当它后续恢复并探测成功时,会被重新加回 Endpoints 列表。
重要的是,readinessProbe 失败不会导致容器被杀死或重启。
使用场景
- 在应用启动时,防止流量过早进入。
- 在应用运行时,如果它需要执行一些耗时的初始化或因为过载而暂时无法处理新请求,可以通过
readinessProbe临时将自己从服务中摘除。
示例配置
apiVersion: v1
kind: Pod
metadata:
name: readiness-pod-example
spec:
containers:
- name: my-app
image: my-app-image
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
启动探针 (Startup Probe)
startupProbe 用于判断容器内的应用是否已经成功启动。
它的出现是为了解决一个棘手的问题:那些启动时间很长或不定的应用,可能会在尚未完成启动时,就被 livenessProbe 错误地判定为“无响应”而被杀死。
工作机制:
- 如果提供了
startupProbe,那么在它成功之前,所有其他的探针(liveness和readiness)都会被禁用。 kubelet会根据periodSeconds和failureThreshold持续执行启动探测。- 如果
startupProbe在其超时预算内(failureThreshold * periodSeconds)成功,kubelet将会接管并开始执行livenessProbe和readinessProbe。 - 如果
startupProbe最终失败,kubelet会杀死并重启容器,就像livenessProbe失败一样。
使用场景
任何启动时间较长或不可预测的应用都应该使用 startupProbe。这对于传统的、庞大的单体应用(如大型 Java 应用)迁移到 Kubernetes 尤为重要。
示例配置
apiVersion: v1
kind: Pod
metadata:
name: startup-pod-example
spec:
containers:
- name: my-slow-app
image: my-slow-app-image
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 10
在此配置中,应用有最多 300 秒(30 * 10)的时间来完成启动。一旦启动探针成功,存活探针将接管,每 10 秒检查一次。
总结与对比
| 探针 (Probe) | 目的 | 失败后的动作 |
|---|---|---|
livenessProbe | 判断容器是否处于“僵死”状态。 | 重启容器。 |
readinessProbe | 判断容器是否准备好接收流量。 | 从 Service Endpoints 中移除该 Pod。 |
startupProbe | 判断应用是否已完成启动,保护慢启动应用。 | 重启容器。 |
如何选择与协同
- 对于启动缓慢或启动时间不固定的应用,总是使用
startupProbe。 - 几乎所有提供网络服务的 Pod 都应该配置
readinessProbe,以优雅地控制流量。 livenessProbe是一把双刃剑。它对于无状态且重启可以解决问题的应用非常有效,但要谨慎配置,避免因外部依赖问题导致不必要的重启。
通过合理地组合使用这三种探针,我们可以构建出真正健壮、具备自愈能力的云原生应用,充分发挥 Kubernetes 的自动化优势。
更多推荐
所有评论(0)