在K8S中,Pod 的健康检查方式有哪些?
好的,这是一个非常核心的Kubernetes概念。Kubernetes 提供了强大而灵活的健康检查机制,主要通过各种探针 (Probe) 来实现,确保您的应用能够稳定可靠地运行。
Pod 的健康检查方式主要分为以下三类,它们协同工作,共同保障应用的健壮性:
1. 存活探针 (Liveness Probe)
核心问题:容器是否还在“活着”且正常运行?
- 目的:检测容器内部的应用是否陷入了死锁、无响应等不可用状态。如果探测失败,kubelet 会杀死并重启容器。
- 作用:解决应用进程存在但服务已挂掉的问题,实现应用的自我修复。
- 类比:就像是对运行中的应用程序问:“你还活着吗?” 如果没有回应,系统就会采取措施(重启)让它恢复活力。
配置示例 (HTTP GET):
apiVersion: v1
kind: Pod
metadata:
name: liveness-example
spec:
containers:
- name: liveness
image: my-app:latest
livenessProbe:
httpGet:
path: /healthz # 应用提供的健康检查端点
port: 8080
initialDelaySeconds: 15 # 容器启动后等待15秒再开始探测
periodSeconds: 10 # 每10秒检查一次
failureThreshold: 3 # 连续失败3次才重启
2. 就绪探针 (Readiness Probe)
核心问题:容器是否已经准备好开始接收外部流量?
- 目的:检测容器是否已经完成初始化,并且可以正常处理请求。如果探测失败,Kubernetes Service 会将这个 Pod 从负载均衡器的端点列表 (Endpoints) 中移除。
- 作用:
- 防止启动过程中的中断:允许容器有足够的时间完成启动(如加载大量数据、连接依赖服务)。
- 处理临时故障:当应用运行时出现暂时性故障(如依赖的外部API短暂不可用),可以将其标记为未就绪,暂时不接收流量,避免用户看到错误。
- 类比:就像是餐厅服务员问后厨:“这道菜准备好了吗?”。如果没准备好,服务员就不会把它端给顾客。它不会重启容器,只是将其与网络流量隔离。
配置示例 (Exec):
apiVersion: v1
kind: Pod
metadata:
name: readiness-example
spec:
containers:
- name: readiness
image: my-app:latest
readinessProbe:
exec:
command: # 执行一个命令检查应用状态
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
3. 启动探针 (Startup Probe) - v1.16+
核心问题:容器内的应用程序是否已经成功启动?
- 目的:保护那些启动速度非常慢的旧有应用或特定应用(例如,需要几十秒甚至几分钟来初始化的Java应用)。
- 作用:在启动探针成功之前,所有其他探针(Liveness 和 Readiness)都会处于禁用状态。这为慢速启动的应用提供了一个“免死金牌”期,避免了在启动期间因为没来得及响应而被 Liveness Probe 误杀重启的窘境。
- 工作方式:启动探针成功后,它的使命就完成了,之后会由存活和就绪探针接管后续的健康检查。
配置示例 (TCP Socket):
apiVersion: v1
kind: Pod
metadata:
name: startup-example
spec:
containers:
- name: startup
image: my-slow-app:latest
startupProbe:
tcpSocket:
port: 8080
failureThreshold: 30 # 尝试足够多的次数
periodSeconds: 5 # 每次尝试间隔5秒
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
在这个例子中,Kubernetes 会尝试最多 30 * 5 = 150 秒的时间来等待应用启动。在此期间,liveness和readiness探针不会执行。
三种探针的协同工作流程
下图清晰地展示了三种探针在 Pod 生命周期中的协同工作流程:
flowchart TD
A[Pod 启动] --> B[启动探针 Enabled?]
B -- Yes --> C[Startup Probe 执行]
C -- Success --> E
C -- Failure --> D[Restart Container] --> A
B -- No --> E[Liveness & Readiness<br>探针激活]
subgraph E[运行阶段]
direction LR
F[Liveness Probe<br>检查容器是否“活着”] <--> G[Readiness Probe<br>检查容器是否“就绪”]
end
E --> H{Liveness 失败?}
H -- Yes --> D
H -- No --> I{Readiness 失败?}
I -- Yes --> J[从 Service Endpoints 移除]
I -- No --> K[正常接收流量]
J --> F
每种探针支持的探测方式
所有三种探针(Startup, Liveness, Readiness)都支持以下三种相同的检测机制:
探测方式 (Handler) | 描述 | 适用场景 |
---|---|---|
exec |
在容器内执行指定命令。如果命令退出码为0,则认为成功。 | 无HTTP服务的应用,可以通过脚本或检查文件是否存在来判断状态。 |
httpGet |
对容器的IP地址和端口执行HTTP GET请求。如果状态码在200-399之间,则认为成功。 | 最常用。适用于Web服务、REST API等任何HTTP应用。 |
tcpSocket |
尝试与容器指定端口建立TCP连接。如果连接成功建立,则认为成功。 | 适用于数据库(MySQL/PostgreSQL)、缓存(Redis)、非HTTP服务等。 |
grpc (v1.24+) |
对gRPC应用执行远程过程调用。 | 专为gRPC微服务设计,效率更高。 |
总结与最佳实践
探针类型 | 失败后果 | 核心用途 | 关键参数建议 |
---|---|---|---|
Liveness Probe | 重启容器 | 从死锁、卡死中恢复应用 | initialDelaySeconds 必须设置合理 |
Readiness Probe | 从Service Endpoints移除Pod | 控制流量接入,保证用户体验 | 检查逻辑应轻量,避免依赖外部服务 |
Startup Probe | 重启容器 | 保护慢启动容器 | failureThreshold * periodSeconds > 最大预估启动时间 |
通用最佳实践:
- 必须定义探针:对于生产环境的应用,几乎总是应该定义 Readiness 和 Liveness 探针。
- 精心设置
initialDelaySeconds
:这是最常见的错误来源。必须给应用留出足够的初始化时间。 - 检查逻辑要轻量:探针检查应该快速、无副作用且不依赖深度外部服务(避免级联故障)。
- 使用专用端点:为 HTTP 探针创建专用的健康检查端点(如
/healthz
和/ready
),不要使用核心业务端点。 - 合理设置超时和阈值:根据应用特性调整
timeoutSeconds
,periodSeconds
, 和failureThreshold
,避免因网络抖动等短暂问题导致误判。
通过组合使用这三种探针,您可以精确地控制 Pod 的生命周期和流量分配,极大地提升应用的韧性和可观测性。