
Kubernetes Pod 健康检查机制 LivenessProbe 与 ReadinessProbe
文章目录
!版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。
系统环境:
- kubernetes 版本:1.14.0
Kubernetes 官方文档地址:
一、Pod 的整个生命阶段
- Pending: 正在创建 Pod,但是 Pod 中的容器还没有全部被创建完成,这其中也包含集群为容器创建网络,或者下载镜像的过程。
- Running: Pod 内所有的容器都已经被创建,且至少一个容器正在处于运行状态、正在启动状态或者重启状态。
- Succeeded: Pod 中所有容器都执行成功后退出,并且没有处于重启的容器。
- Failed: Pod 中所有容器都已退出,但是至少还有一个容器退出时为失败状态。
- Unknown: 由于一些原因,Pod 的状态无法获取,通常是与 Pod 通信时出错导致的。

二、Pod 重启策略
- Always: 只要容器失效退出就重新启动容器。
- OnFailure: 当容器以非正常退出后重新启动容器。
- Never: 无论容器状态如何,都不重新启动容器。
如果 restartpolicy 没有设置,那么默认值是 Always。RC 和 DaemonSet 必须指定重启策略为 Always。
三、Pod 常见状态转换场景
| Pod中的容器数 | Pod状态 | 发生事件 | 不同重启策略下的结果状态 | ||
|---|---|---|---|---|---|
| Always | OnFailure | Never | |||
| 包含一个容器 | Running | 容器成功退出 | Running | Succeeded | Succeeded |
| 包含一个容器 | Running | 容器失败退出 | Running | Running | Failed |
| 包含两个容器 |
Running | 1个容器失败退出 | Running | Running | Running |
| 包含两个容器 | Running | 容器内存溢出挂掉 | Running | Running | Failed |
四、Pod 的活性与就绪探针
1、Pod 探针机制
在 Kubernetes 中 Pod 是最小的计算单元,而一个 Pod 又由多个容器组成,相当于每个容器就是一个应用,应用在运行期间,可能因为某也意外情况致使程序挂掉。那么如何监控这些容器状态稳定性,保证服务在运行期间不会发生问题,发生问题后进行重启等机制,就成为了重中之重的事情,考虑到这点 kubernetes 推出了活性探针机制。
有了活性探针后能保证程序在运行中如果挂掉能够自动重启,但是还有个经常遇到的问题,比如说,在 Kubernetes 中启动 Pod,显示明明 Pod 已经启动成功,且能访问里面的端口,但是却返回错误信息。还有就是在执行滚动更新时候,总会出现一段时间,Pod 对外提供网络访问,但是访问却发生 404,这两个原因,都是因为 Pod 已经成功启动,但是 Pod 的的容器中应用程序还在启动中导致,考虑到这点 Kubernetes 推出了就绪探针机制。
2、Pod 两种探针简介
-
LivenessProbe(存活探针): 存活探针主要作用是,用指定的方式进入容器检测容器中的应用是否正常运行,如果检测失败,则认为容器不健康,那么
Kubelet将根据Pod中设置的restartPolicy(重启策略)来判断,Pod 是否要进行重启操作,如果容器配置中没有配置livenessProbe存活探针,Kubelet将认为存活探针探测一直为成功状态。 -
ReadinessProbe(就绪探针): 用于判断容器中应用是否启动完成,当探测成功后才使 Pod 对外提供网络访问,设置容器
Ready状态为true,如果探测失败,则设置容器的Ready状态为false。对于被 Service 管理的 Pod,Service与Pod、EndPoint的关联关系也将基于 Pod 是否为Ready状态进行设置,如果 Pod 运行过程中Ready状态变为false,则系统自动从Service关联的EndPoint列表中移除,如果 Pod 恢复为Ready状态。将再会被加回Endpoint列表。通过这种机制就能防止将流量转发到不可用的 Pod 上。
3、Pod 探针的探测方式与结果
目前 LivenessProbe 和 ReadinessProbe 两种探针都支持下面三种探测方法:
- ExecAction: 在容器中执行指定的命令,如果能成功执行,则探测成功。
- HTTPGetAction: 通过容器的IP地址、端口号及路径调用 HTTP Get 方法,如果响应的状态码 200 ≤ status ≤ 400,则认为容器探测成功。
- TCPSocketAction: 通过容器的 IP 地址和端口号执行 TCP 检查,如果能够建立 TCP 连接,则探测成功。
探针探测结果有以下值:
- Success:表示通过检测。
- Failure:表示未通过检测。
- Unknown:表示检测没有正常进行。
4、Pod 探针的相关属性
两种探针有许多可选字段,可以用来更加精确的控制 LivenessProbe 和 ReadinessProbe 两种探针的探测,具体如下:
- initialDelaySeconds: Pod 启动后首次进行检查的等待时间,单位“秒”。
- periodSeconds: 检查的间隔时间,默认为 10s,单位“秒”。
- timeoutSeconds: 探针执行检测请求后,等待响应的超时时间,默认为 1s,单位“秒”。
- successThreshold: 探针检测失败后认为成功的最小连接成功次数,默认为 1s,在 Liveness 探针中必须为 1s,最小值为 1s。
- failureThreshold: 探测失败的重试次数,重试一定次数后将认为失败,在 readiness 探针中,Pod会被标记为未就绪,默认为 3s,最小值为 1s。
5、两种探针的区别
总的来说 ReadinessProbe 和 LivenessProbe 是使用相同探测的方式,只是探测后对 Pod 的处置方式不同:
- ReadinessProbe: 当检测失败后,将 Pod 的 IP:Port 从对应 Service 关联的 EndPoint 地址列表中删除。
- LivenessProbe: 当检测失败后将杀死容器,并根据 Pod 的重启策略来决定作出对应的措施。
五、探针使用示例
1、LivenessProbe 探针使用示例
(1)、通过 Exec 方式做健康探测
示例文件 liveness-exec.yaml
1apiVersion: v1
2kind: Pod
3metadata:
4 name: liveness-exec
5 labels:
6 app: liveness
7spec:
8 containers:
9 - name: liveness
10 image: busybox
11 args: #创建测试探针探测的文件
12 - /bin/sh
13 - -c
14 - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
15 livenessProbe:
16 initialDelaySeconds: 10 #延迟检测时间
17 periodSeconds: 5 #检测时间间隔
18 exec:
19 command:
20 - cat
21 - /tmp/healthy
容器启动设置执行的命令:
1/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
容器在初始化后,首先创建一个 /tmp/healthy 文件,然后执行睡眠命令,睡眠 30 秒,到时间后执行删除 /tmp/healthy 文件命令。而设置的存活探针检检测方式为执行 shell 命令,用 cat 命令输出 healthy 文件的内容,如果能成功执行这条命令,存活探针就认为探测成功,否则探测失败。在前 30 秒内,由于文件存在,所以存活探针探测时执行 cat /tmp/healthy 命令成功执行。30 秒后 healthy 文件被删除,所以执行命令失败,Kubernetes 会根据 Pod 设置的重启策略来判断,是否重启 Pod。
(2)、通过 HTTP 方式做健康探测
示例文件 liveness-http.yaml
1apiVersion: v1
2kind: Pod
3metadata:
4 name: liveness-http
5 labels:
6 test: liveness
7spec:
8 containers:
9 - name: liveness
10 image: mydlqclub/springboot-helloworld:0.0.1
11 livenessProbe:
12 initialDelaySeconds: 20 #延迟加载时间
13 periodSeconds: 5 #重试时间间隔
14 timeoutSeconds: 10 #超时时间设置
15 httpGet:
16 scheme: HTTP
17 port: 8081
18 path: /actuator/health
上面 Pod 中启动的容器是一个 SpringBoot 应用,其中引用了 Actuator 组件,提供了 /actuator/health 健康检查地址,存活探针可以使用 HTTPGet 方式向服务发起请求,请求 8081 端口的 /actuator/health 路径来进行存活判断:
- 探测结果的 Http 状态码如果为 200 ≤ status ≤ 400 的代码,则表示探测成功。
如果探测失败,则会杀死 Pod 进行重启操作。
httpGet探测方式有如下可选的控制字段:
- scheme: 用于测试连接的协议,默认为 HTTP。
- host: 要连接的主机名,默认为 Pod IP。
- port: 容器上要访问端口号或名称。
- path: Http 服务器上的访问 URL。
- httpHeaders: 自定义 Http 请求 Headers,Http 允许重复 Headers。
(3)、通过 TCP 方式做健康探测
示例文件 liveness-tcp.yaml
1apiVersion: v1
2kind: Pod
3metadata:
4 name: liveness-tcp
5 labels:
6 app: liveness
7spec:
8 containers:
9 - name: liveness
10 image: nginx
11 livenessProbe:
12 initialDelaySeconds: 15
13 periodSeconds: 20
14 tcpSocket:
15 port: 80
TCP 检查方式和 HTTP 检查方式非常相似,在容器启动 initialDelaySeconds 参数设定的时间后,kubelet 将发送第一个 livenessProbe 探针,尝试连接容器的 80 端口,如果连接失败则将杀死 Pod 重启容器。
2、ReadinessProbe 探针使用示例
Pod 的 ReadinessProbe 探针使用方式和 LivenessProbe 探针探测方法一样,也是支持三种,只是一个是用于探测应用的存活,一个是判断是否对外提供流量的条件。这里用一个 Springboot 项目,设置 ReadinessProbe 探测 SpringBoot 项目的 8081 端口下的 /actuator/health 接口,如果探测成功则代表内部程序已经成功启动,就开放对外提供接口访问,否则内部应用没有成功启动或者在启动中,暂不对外提供访问,直到就绪探针探测成功才允许访问。
示例文件 readiness-exec.yaml
1apiVersion: v1
2kind: Service
3metadata:
4 name: springboot
5 labels:
6 app: springboot
7spec:
8 type: NodePort
9 ports:
10 - name: server
11 port: 8080
12 targetPort: 8080
13 nodePort: 31180
14 - name: management
15 port: 8081
16 targetPort: 8081
17 nodePort: 31181
18 selector:
19 app: springboot
20---
21apiVersion: v1
22kind: Pod
23metadata:
24 name: springboot
25 labels:
26 app: springboot
27spec:
28 containers:
29 - name: springboot
30 image: mydlqclub/springboot-helloworld:0.0.1
31 ports:
32 - name: server
33 containerPort: 8080
34 - name: management
35 containerPort: 8081
36 readinessProbe:
37 initialDelaySeconds: 20
38 periodSeconds: 5
39 timeoutSeconds: 10
40 httpGet:
41 scheme: HTTP
42 port: 8081
43 path: /actuator/health
3、ReadinessProbe + LivenessProbe 配合使用示例
一般程序中需要设置两种探针结合使用,并且也要结合实际情况,来配置初始化检查时间和检测间隔,下面列一个简单的 SpringBoot 项目的 Deployment 例子。
1apiVersion: v1
2kind: Service
3metadata:
4 name: springboot
5 labels:
6 app: springboot
7spec:
8 type: NodePort
9 ports:
10 - name: server
11 port: 8080
12 targetPort: 8080
13 nodePort: 31180
14 - name: management
15 port: 8081
16 targetPort: 8081
17 nodePort: 31181
18 selector:
19 app: springboot
20---
21apiVersion: apps/v1
22kind: Deployment
23metadata:
24 name: springboot
25 labels:
26 app: springboot
27spec:
28 replicas: 1
29 selector:
30 matchLabels:
31 app: springboot
32 template:
33 metadata:
34 name: springboot
35 labels:
36 app: springboot
37 spec:
38 containers:
39 - name: readiness
40 image: mydlqclub/springboot-helloworld:0.0.1
41 ports:
42 - name: server
43 containerPort: 8080
44 - name: management
45 containerPort: 8081
46 readinessProbe:
47 initialDelaySeconds: 20
48 periodSeconds: 5
49 timeoutSeconds: 10
50 httpGet:
51 scheme: HTTP
52 port: 8081
53 path: /actuator/health
54 livenessProbe:
55 initialDelaySeconds: 30
56 periodSeconds: 10
57 timeoutSeconds: 5
58 httpGet:
59 scheme: HTTP
60 port: 8081
61 path: /actuator/health
---END---
!版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。