【K8S学习之探针】详细了解就绪探针 readinessProbe 和存活探针 livenessProbe 的配置
参考
- Pod健康检查 · Kubernetes 学习笔记
- Kubernetes 就绪探针(Readiness Probe) - 人艰不拆_zmc - 博客园
- Kubernetes存活探针(Liveness Probe) - 人艰不拆_zmc - 博客园
Pod健康检查
Pod的健康状态由两类探针来检查:LivenessProbe
和ReadinessProbe
。
探针种类 | 作用 | 使用场景 |
---|---|---|
readinessProbe(就绪探针) | 控制是否流量接入 控制Pod 的 Ready 状态(流量路由相关) | 适用于应用初始化过程较长;gRPC 服务准备需等待 |
livenessProbe(存活探针) | 控制pod内容器是否重启 控制Pod 内容器 的 生死状态(Kubelet 是否重启) 同时容器的重启需要指定 restartPolicy 为 Always 或 OnFailure | 适用于防止容器挂死、内存泄漏、死循环等 |
简单描述流程
┌─────────────┐
│ Pod 启动中 │
└─────┬───────┘│ readinessProbe▼
┌──────────────┐
│ Ready = True │ ←─→ 接收流量、被 sidecar 调用
└──────────────┘│ livenessProbe▼健康失败 → 自动重启容器
restartPolicy 直观对比
- 配置在 Pod 中,.spec 下
restartPolicy | 会在容器退出后重启? | 典型用途 |
---|---|---|
Always | ✅ 任何原因退出都会重启 | 长期运行服务,如 Web 服务、CSI 插件 |
OnFailure | ✅ 仅退出码 ≠ 0 才会重启 | 批处理任务,失败时尝试重跑 |
Never | ❌ 不重启 | 调试、测试、一次性运行 |
默认 restartPolicy
对照表
控制器类型 | 默认 restartPolicy | 是否自动重启容器 |
---|---|---|
Deployment | Always | ✅ 是,容器退出或探针失败会自动重启 |
StatefulSet | Always | ✅ 是 |
DaemonSet | Always | ✅ 是 |
Job | OnFailure | ✅ 是,仅任务失败时重启 |
CronJob | OnFailure | ✅ 是 |
裸 Pod(无控制器) | Always (如未手动设置) | ✅ 是,但需要 Kubelet 能重启 |
手动设置 | Never / OnFailure / Always | 根据设置决定 |
通用配置参数
常用的参数为timeoutSeconds
、periodSeconds
、periodSeconds
,即接口超时时间,重试频率,重试次数三个值。
initialDelaySeconds
:启动容器后首次进行健康检查的等待时间,单位为秒,默认值为0。timeoutSeconds
:健康检查接口超时响应的时间,默认为1秒,最小值为1秒。periodSeconds
:重试的频率,默认值为10秒,即10秒重试一次,最小值是1秒,建议可以设置为3-5秒。failureThreshold
:失败重试的次数,默认值为3,最小值为1。successThreshold
:最小探测成功次数,默认值为1,一般不设置。
除了以上的通用参数外,livenessProbe
和readinessProbe
参数基本一致。以下以readinessProbe
为例说明探针的使用方式。
探测方式
三种探测方式总览
类型 | 探测方式 | 说明 | 举例 |
---|---|---|---|
HTTP | httpGet | 发 HTTP 请求,期待 2xx/3xx 状态码; 不支持鉴权 | Web 服务、HTTP 接口检查 |
TCP | tcpSocket | 检查端口是否能连接(TCP 三次握手) | 检查 Redis、MySQL 存活 |
Exec | exec | 容器内执行命令,0 为成功,非 0 为失败 | 检查文件、socket、自定义命令 |
建议
应用类型 | 推荐探测方式 |
---|---|
Web 服务 | HTTP |
数据库、缓存服务 | TCP 或 Exec |
gRPC、CSI 插件等非 HTTP 应用 | Exec |
1️⃣ HTTP 探测(适合 Web 服务)
readinessProbe:httpGet:path: /healthzport: 8080initialDelaySeconds: 3periodSeconds: 10
---
livenessProbe:httpGet:path: /liveport: 8080initialDelaySeconds: 5periodSeconds: 15
- Kubernetes 的 HTTP 探针 (
httpGet
) 不支持设置鉴权(如 Header、Token、Basic Auth 等),它只能发起一个非常基础的 无认证的 GET 请求- 支持的基本认证方式(有限),可以手动加上 Basic Auth 或静态 Token,例如:
livenessProbe:httpGet:path: /healthzport: 8080host: 127.0.0.1scheme: HTTPhttpHeaders: # ✅ 仅支持自定义 Header(有限的鉴权)# 虽然可以配置 httpHeaders,但它仅支持添加固定值的请求头,不支持动态 Token、OAuth、JWT 等复杂认证机制。- name: X-Customvalue: some-value
---
# 支持的基本认证方式(有限)
# 可以手动加上 Basic Auth 或静态 Token,例如:
# ⚠️ 注意:Kubernetes 不会自动加密或刷新 Token,不适合需要动态鉴权的系统。
livenessProbe:httpGet:path: /healthzport: 8080scheme: HTTPhttpHeaders:- name: Authorizationvalue: "Bearer your-static-token"
-
更复杂鉴权怎么办?
-
如果你的健康检查接口需要:
- JWT 验证
- OAuth 令牌
- mTLS
- Cookie 会话
你有两个常见替代方案:
# 🔁 方案 1:增加一个 无鉴权的 /healthz 路由
# 让健康检查接口跳过鉴权,例如:
# 这是最推荐的方案,被广泛使用。
if req.URL.Path == "/healthz" {return 200
}
---
# 🛠️ 方案 2:用 Exec 或 Sidecar 转发带 Token 的请求
# 写一个 shell 脚本用 curl 加 Token:
# 或在容器里运行一个 sidecar 服务专门处理健康探测转发。
exec:command:- /bin/sh- -c- curl -H "Authorization: Bearer $MY_TOKEN" http://localhost:8080/secure-health
2️⃣ TCP 探测(适合没有健康接口的服务)
livenessProbe:tcpSocket:port: 3306initialDelaySeconds: 10periodSeconds: 20
这个探针只会判断 TCP 端口是否能连通,不判断服务逻辑是否正常。
3️⃣ Exec 探测(适合非 HTTP 应用,如 CSI 插件)
readinessProbe:exec:command:- /bin/sh- -c- 'test -S /csi/csi.sock'initialDelaySeconds: 5periodSeconds: 10
这类适合自定义协议、gRPC、检查 Unix socket 文件等场景。
详解
1. 探针类型
1. livenessProbe(存活探针)
- 表明容器是否正在运行。
- 如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其
重启策略
的影响。 - 如果容器不提供存活探针,则默认状态为
Success
。
2. readinessProbe(就绪探针)
- 表明容器是否可以正常接受请求。
- 如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。
- 初始延迟之前的就绪状态默认为
Failure
。 - 如果容器不提供就绪探针,则默认状态为
Success
。
2. 探针使用场景
- 如果容器异常可以自动崩溃,则不一定要使用探针,可以由Pod的
restartPolicy
执行重启操作。 存活探针
适用于希望容器探测失败后被杀死并重新启动,需要指定restartPolicy
为 Always 或 OnFailure。就绪探针
适用于希望Pod在不能正常接收流量的时候被剔除,并且在就绪探针探测成功后才接收流量。
探针
是kubelet
对容器执行定期的诊断,主要通过调用容器配置的四类Handler
实现:
Handler的类型:
ExecAction
:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。TCPSocketAction
:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。HTTPGetAction
:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。GRPCAction
:调用GRPC接口来判断服务是否健康。 如果响应的状态是 “SERVING”,则认为诊断成功。
探测结果为以下三种之一:
成功
:容器通过了诊断。失败
:容器未通过诊断。未知
:诊断失败,因此不会采取任何行动。
3. 探针的配置
探针配置在pod的container结构体下,livenessProbe
和readinessProbe
参数基本一致。
3.1. 探针通用参数
常用的参数为timeoutSeconds
、periodSeconds
、periodSeconds
,即接口超时时间,重试频率,重试次数三个值。
initialDelaySeconds
:启动容器后首次进行健康检查的等待时间,单位为秒,默认值为0。timeoutSeconds
:健康检查接口超时响应的时间,默认为1秒,最小值为1秒。periodSeconds
:重试的频率,默认值为10秒,即10秒重试一次,最小值是1秒,建议可以设置为3-5秒。failureThreshold
:失败重试的次数,默认值为3,最小值为1。successThreshold
:最小探测成功次数,默认值为1,一般不设置。
除了以上的通用参数外,livenessProbe
和readinessProbe
参数基本一致。以下以readinessProbe
为例说明探针的使用方式。
3.2. ReadinessProbe三种实现方式
3.2.1. HTTPGetAction
通过容器的IP地址、端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于等于400,则认为容器健康。
apiVersion: v1
kind: Pod
metadata:name: pod-with-healthcheck
spec:restartPolicy: Always # ⭐ 容器探针依赖此项自动重启,默认也是 Always 或 OnFailurecontainers:- name: nginximage: nginxports:- containnerPort: 80readinessProbe:httpGet:path: /_status/healthzport: 80scheme: HTTPinitialDelaySeconds: 1periodSeconds: 5timeoutSeconds: 5
3.2.2. TCPSocketAction
通过容器IP地址和端口号执行TCP检查,如果能够建立TCP连接,则表明容器健康。
apiVersion: v1
kind: Pod
metadata:name: pod-with-healthcheck
spec:containers:- name: nginximage: nginxports:- containnerPort: 80readinessProbe:tcpSocket:port: 80initialDelaySeconds: 1timeoutSeconds: 5
3.2.3. ExecAction
在一个容器内部执行一个命令,如果该命令状态返回值为0,则表明容器健康。
apiVersion: v1
kind: Pod
metadata:name: readiness-exec
spec:containers:- name: readinessimage: tomcagcr.io/google_containers/busyboxargs:- /bin/sh- -c- echo ok > /tmp/health;sleep 10;rm -fr /tmp/health;sleep 600readinessreadinessProbe:exec:command:- cat- /tmp/healthinitialDelaySeconds: 1timeoutSeconds: 5
4. 探针相关源码
探针配置在pod的container结构体下:
// 存活探针LivenessProbe *Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"`// 就绪探针ReadinessProbe *Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
4.1. Probe源码
type Probe struct {// The action taken to determine the health of a containerProbeHandler `json:",inline" protobuf:"bytes,1,opt,name=handler"`// Number of seconds after the container has started before liveness probes are initiated.// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes// +optionalInitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty" protobuf:"varint,2,opt,name=initialDelaySeconds"`// Number of seconds after which the probe times out.// Defaults to 1 second. Minimum value is 1.// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes// +optionalTimeoutSeconds int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,3,opt,name=timeoutSeconds"`// How often (in seconds) to perform the probe.// Default to 10 seconds. Minimum value is 1.// +optionalPeriodSeconds int32 `json:"periodSeconds,omitempty" protobuf:"varint,4,opt,name=periodSeconds"`// Minimum consecutive successes for the probe to be considered successful after having failed.// Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.// +optionalSuccessThreshold int32 `json:"successThreshold,omitempty" protobuf:"varint,5,opt,name=successThreshold"`// Minimum consecutive failures for the probe to be considered failed after having succeeded.// Defaults to 3. Minimum value is 1.// +optionalFailureThreshold int32 `json:"failureThreshold,omitempty" protobuf:"varint,6,opt,name=failureThreshold"`// Optional duration in seconds the pod needs to terminate gracefully upon probe failure.// The grace period is the duration in seconds after the processes running in the pod are sent// a termination signal and the time when the processes are forcibly halted with a kill signal.// Set this value longer than the expected cleanup time for your process.// If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this// value overrides the value provided by the pod spec.// Value must be non-negative integer. The value zero indicates stop immediately via// the kill signal (no opportunity to shut down).// This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.// Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.// +optionalTerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" protobuf:"varint,7,opt,name=terminationGracePeriodSeconds"`
}
4.2. ProbeHandler源码
// ProbeHandler defines a specific action that should be taken in a probe.
// One and only one of the fields must be specified.
type ProbeHandler struct {// Exec specifies the action to take.// +optionalExec *ExecAction `json:"exec,omitempty" protobuf:"bytes,1,opt,name=exec"`// HTTPGet specifies the http request to perform.// +optionalHTTPGet *HTTPGetAction `json:"httpGet,omitempty" protobuf:"bytes,2,opt,name=httpGet"`// TCPSocket specifies an action involving a TCP port.// +optionalTCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" protobuf:"bytes,3,opt,name=tcpSocket"`// GRPC specifies an action involving a GRPC port.// This is a beta field and requires enabling GRPCContainerProbe feature gate.// +featureGate=GRPCContainerProbe// +optionalGRPC *GRPCAction `json:"grpc,omitempty" protobuf:"bytes,4,opt,name=grpc"`
}
4.3. ProbeAction
4.3.1. HTTPGetAction
// HTTPHeader describes a custom header to be used in HTTP probes
type HTTPHeader struct {// The header field nameName string `json:"name" protobuf:"bytes,1,opt,name=name"`// The header field valueValue string `json:"value" protobuf:"bytes,2,opt,name=value"`
}// HTTPGetAction describes an action based on HTTP Get requests.
type HTTPGetAction struct {// Path to access on the HTTP server.// +optionalPath string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"`// Name or number of the port to access on the container.// Number must be in the range 1 to 65534. // Name must be an IANA_SVC_NAME.Port intstr.IntOrString `json:"port" protobuf:"bytes,2,opt,name=port"`// Host name to connect to, defaults to the pod IP. You probably want to set// "Host" in httpHeaders instead.// +optionalHost string `json:"host,omitempty" protobuf:"bytes,3,opt,name=host"`// Scheme to use for connecting to the host.// Defaults to HTTP.// +optionalScheme URIScheme `json:"scheme,omitempty" protobuf:"bytes,4,opt,name=scheme,casttype=URIScheme"`// Custom headers to set in the request. HTTP allows repeated headers.// +optionalHTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty" protobuf:"bytes,5,rep,name=httpHeaders"`
}// URIScheme identifies the scheme used for connection to a host for Get actions
// +enum
type URIScheme stringconst (// URISchemeHTTP means that the scheme used will be http://URISchemeHTTP URIScheme = "HTTP"// URISchemeHTTPS means that the scheme used will be https://URISchemeHTTPS URIScheme = "HTTPS"
)
4.3.2. TCPSocketAction
// TCPSocketAction describes an action based on opening a socket
type TCPSocketAction struct {// Number or name of the port to access on the container.// Number must be in the range 1 to 65534. // Name must be an IANA_SVC_NAME.Port intstr.IntOrString `json:"port" protobuf:"bytes,1,opt,name=port"`// Optional: Host name to connect to, defaults to the pod IP.// +optionalHost string `json:"host,omitempty" protobuf:"bytes,2,opt,name=host"`
}
4.3.3. ExecAction
// ExecAction describes a "run in container" action.
type ExecAction struct {// Command is the command line to execute inside the container, the working directory for the// command is root ('/') in the container's filesystem. The command is simply exec'd, it is// not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use// a shell, you need to explicitly call out to that shell.// Exit status of 0 is treated as live/healthy and non-zero is unhealthy.// +optionalCommand []string `json:"command,omitempty" protobuf:"bytes,1,rep,name=command"`
}
4.3.4. GRPCAction
type GRPCAction struct {// Port number of the gRPC service. Number must be in the range 1 to 65534. Port int32 `json:"port" protobuf:"bytes,1,opt,name=port"`// Service is the name of the service to place in the gRPC HealthCheckRequest// (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).//// If this is not specified, the default behavior is defined by gRPC.// +optional// +default=""Service *string `json:"service" protobuf:"bytes,2,opt,name=service"`
}
参考文章:
- https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
- 配置存活、就绪和启动探针 | Kubernetes
- https://mp.weixin.qq.com/s/ApD8D0_UAPftUjw-0Txcyw
- 《Kubernetes权威指南》