前言:
分布式系统和微服务体系结构的挑战之一是自动检测不正常的应用程序,并将请求(request)重新路由到其他可用系统,恢复损坏的组件。健康检查是应对该挑战的一种可靠方法。使用 Kubernetes,可以通过探针配置运行状况检查,以确定每个 Pod 的状态。
.
摘要:Kubernetes 版本小于 v1.15 时支持 Readiness 和 Liveness 探针,在 v1.16 中添加了 startup 探针作为 Alpha 功能,并在 v1.18 中升级为 Beta。
.
一、探针类型介绍:
(1)、K8s中存在三种类型的探针:liveness probe、readiness probe和startup 探针。每类探针都支持三种探测方法
liveness探针
:影响的是单个容器,如果检查失败,将杀死容器,根据pod的restartPolicy来操作。readiness探针
:影响的是整个pod,即如果pod中有多个容器,只要有一个容器的readiness探针诊断失败,那么整个pod都会处于unready状态。startup探针
:指示容器中的应用是否已经启动。如果提供了启动探针(startup probe),则禁用所有其他探针,直到它成功为止。如果启动探针失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探针,则默认状态为成功Success。
(2)、这三种探针均具有以下参数:
- initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。
- periodSeconds:执行探测的频率。默认是10秒,最小1秒。
- timeoutSeconds:探测超时时间。默认1秒,最小1秒。
- successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。
- failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
(3)、探针探测的结果有以下三者之一:
- Success:Container通过了检查。
- Failure:Container未通过检查。
- Unknown:未能执行检查,因此不采取任何措施。
1、liveness probe(存活探针)
必要性:
在一个服务中,是存在进程在运行,但服务其实已经挂掉了,表现为端口监听失败、http请求失败等。所以需要存活探针
运行原理:
用于判断容器是否存活,即Pod是否为running状态,如果LivenessProbe探针探测到容器不健康,则kubelet将kill掉容器,并根据容器的重启策略是否重启。
如果一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。
有时应用程序可能因为某些原因(后端服务故障等)导致暂时无法对外提供服务,但应用软件没有终止,导致K8S无法隔离有故障的pod,调用者可能会访问到有故障的pod,导致业务不稳定。
K8S提供livenessProbe来检测应用程序是否正常运行,并且对相应状况进行相应的补救措施。
注意,liveness探测失败并一定不会重启pod,pod是否会重启由你的restart policy 控制。
2、readiness probe(就绪探针)
运行原理:
用于判断容器是否启动完成,即容器的Ready是否为True,可以接收请求,如果ReadinessProbe探测失败,
则容器的Ready将为False,控制器将此Pod的Endpoint从对应的service的Endpoint列表中移除,从此不再将任何请求调度此Pod上,直到下次探测成功。
通过使用Readiness探针,Kubernetes能够等待应用程序完全启动,然后才允许服务将流量发送到新副本。
关于 Readiness 探针有一点很重要,它会在容器的整个生命周期中运行。这意味着 Readiness 探针不仅会在启动时运行,而且还会在 Pod 运行期间反复运行。这是为了处理应用程序暂时不可用的情况(比如加载大量数据、等待外部连接时)。在这种情况下,我们不一定要杀死应用程序,可以等待它恢复。Readiness 探针可用于检测这种情况,并在 Pod 再次通过 Readiness 检查后,将流量发送到这些 Pod。
3、Startup probe(启动探针)
运行原理:
startup 探针与 Readiness 探针类似,但它仅在启动时执行,能针对启动缓慢的容器或在初始化过程中有不可预测行为的应用程序进行优化。借助 Readiness 探针,我们可以配置 initialDelaySeconds 来确定 Readiness 探测在准备就绪前要等待多长时间。
二、探针探测方法介绍:
- exec通过执行shell命令的方式,判断退出状态码是否是0,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。
- tcpSocket:通过容器的IP和Port执行TCP检查,kubelet尝试打开容器上的某个端口,如果能够建立TCP连接,则表明容器健康。
- httpGet通过发送http请求检查服务是否正常,每进行一次HTTP健康检查都会curl访问一次指定的URL,返回200-399状态码则表明容器健康,否则认为容器运转不正常。
1、HTTP
kubelet 将 HTTP GET 请求发送到 endpoint,并检查 2xx 或 3xx 响应。我们可以重复使用现有的 HTTP endpoint 或设置轻量级 HTTP 服务器以进行探测(例如,具有 /healthz endpoint 的 Express server)。HTTP 探针包含其他额外参数:
- host:要连接的主机名(默认值:pod 的 IP)。
- scheme:HTTP(默认)或 HTTPS。
- path:HTTP/S 服务器上的路径 。
- httpHeaders:自定义标头(如果需要标头用于身份验证、CORS 设置等) 。
- port:访问服务器的端口名称或端口号。
livenessProbe:
httpGet:
path: /
port: 8080
2、TCP
如果仅需要检查是否可以建立 TCP 连接,则可以指定 TCP 探针。如果建立 TCP 连接,则将 Pod 标记为运行状况良好。对于不适合使用 HTTP 探针的 gRPC 或 FTP 服务器,TCP 探针可能会有用。
readinessProbe:
tcpSocket:
port: 20
3、Command
可以将探针配置为运行 shell 命令。如果命令返回的退出代码为 0,则检查通过,否则 Pod 将被标记为不健康。如果不希望公开 HTTP 服务器与端口,或者希望通过命令检查初始化步骤(例如,检查是否已创建配置文件、运行 CLI 命令),这种类型的探针会很有用。
readinessProbe:
exec:
command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"]
三、用法实例:
点击查看代码
readinessProbe:
httpGet:
path: {{ .Values.probe.readiness }}
port: {{ .Values.insInsuranceApi.service.targetPort }}
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 90
periodSeconds: 10
successThreshold: 3
timeoutSeconds: 1
livenessProbe:
httpGet:
path: {{ .Values.probe.liveness }}
port: {{ .Values.insInsuranceApi.service.targetPort }}
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 180
periodSeconds: 10
timeoutSeconds: 120