目录
存活、就绪和启动探针
存活探针(Liveness Probe)
就绪探针(Readiness Probe)
启动探针(Startup Probe)
检测方式:
exec:
HTTP GET:
TCP Socket:
grpc:
配置探针
配置存活探针:
定义存活探测命令:
定义一个存活态 HTTP 请求接口
定义 TCP 的存活探测
配置就绪探针
配置启动探针
探针的配置字段
存活、就绪和启动探针
存活探针(Liveness Probe)
存活探针决定何时重启容器。 例如,当应用在运行但无法取得进展时,存活探针可以捕获这类死锁。
如果一个容器的存活探针失败多次,kubelet 将重启该容器。
存活探针不会等待就绪探针成功。 如果你想在执行存活探针前等待,你可以定义 initialDelaySeconds,或者使用启动探针。
就绪探针(Readiness Probe)
就绪探针决定何时容器准备好开始接受流量。 这种探针在等待应用执行耗时的初始任务时非常有用,例如建立网络连接、加载文件和预热缓存。
如果就绪探针返回的状态为失败,Kubernetes 会将该 Pod 从所有对应服务的端点中移除,并且不会将该Pod的IP地址添加到对应Service的负载均衡池中,从而避免将流量路由到该容器。
就绪探针在容器的整个生命期内持续运行。
启动探针(Startup Probe)
启动探针检查容器内的应用是否已启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被 kubelet 杀掉。
如果配置了这类探针,它会禁用存活检测和就绪检测,直到启动探针成功为止。
这类探针仅在启动时执行,不像就绪探针那样周期性地运行。
检测方式:
exec:
在容器内执行特定命令,根据命令的退出状态码来判断是否成功。如果命令返回状态码为0,则认为容器是健康的;否则,认为容器不健康。
HTTP GET:
对容器的IP地址上的指定端口和路径执行HTTP GET请求。如果响应的状态码在200-399之间,则认为容器是健康的。
TCP Socket:
检查容器的指定端口是否能够接受TCP连接。如果连接成功,则认为容器是健康的。
grpc:
v1.27以上版本适用
通过gRPC协议与容器内的应用程序通信,并基于应用程序的响应来判断其是否健康。如"SERVING",Kubernetes会认为这次健康检查是成功的,并据此判断容器是健康的。
配置探针
配置存活探针:
定义存活探测命令:
创建pod并以 busybox 为基础镜像的yaml文件:
[root@k8s-master-1 probe]# vim liveness.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
在这个配置文件中, periodSeconds
字段指定了 kubelet 应该每 5 秒执行一次存活探测;
initialDelaySeconds
字段告诉 kubelet 在执行第一次探测前应该等待 5 秒;
kubelet 在容器内执行命令 cat /tmp/healthy
来进行探测,如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的;
如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"
这个容器生命的前 30 秒,/tmp/healthy
文件是存在的。 所以在这最开始的 30 秒内,执行命令 cat /tmp/healthy
会返回成功代码, 30 秒之后,执行命令 cat /tmp/healthy
就会返回失败代码。
创建pod并查看其信息:
[root@k8s-master-1 probe]# kubectl apply -f liveness.yaml
[root@k8s-master-1 probe]# kubectl describe pod liveness-exec
前30s显示的信息,表明还没有存活探针失败:
再过5s后显示的信息,在输出结果的最下面,表示有信息显示存活探针失败了,这个失败的容器被杀死并且被重建了。
再等 30 秒,输出结果显示 RESTARTS
的值增加了 1, 失败的容器恢复为运行状态,RESTARTS
计数器就会增加 1,确认这个容器被重启了:
定义一个存活态 HTTP 请求接口
下面是一个 Pod 的配置文件,其中运行一个基于 registry.k8s.io/e2e-test-images/agnhost
镜像的容器
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: registry.k8s.io/e2e-test-images/agnhost:2.40
args:
- liveness
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
在这个配置文件中, periodSeconds
字段指定了 kubelet 每隔 3 秒执行一次存活探测,initialDelaySeconds
字段告诉 kubelet 在执行第一次探测前应该等待 3 秒;
kubelet 会向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测, 如果服务器上 /healthz
路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的, 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启;
返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。
容器存活期间的最开始 10 秒中,/healthz
处理程序返回 200 的状态码, 之后处理程序返回 500 的状态码。
kubelet 在容器启动之后 3 秒开始执行健康检查。所以前几次健康检查都是成功的。 但是 10 秒之后,健康检查会失败,并且 kubelet 会杀死容器再重新启动容器。
10 秒之后,通过查看 Pod 事件来确认存活探针已经失败,并且容器被重新启动了:
[root@k8s-master-1 probe]# kubectl describe pod liveness-http
定义 TCP 的存活探测
使用这种配置时,kubelet 会尝试在指定端口和容器建立套接字链接。
如果能建立连接,这个容器就被看作是健康的,如果不能则这个容器就是不健康的。
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: registry.k8s.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
这个例子同时使用就绪探针和存活探针;
kubelet 会在容器启动 15 秒后运行第一次存活探测, 此探测会尝试连接 goproxy
容器的 8080 端口, 如果此存活探测失败,容器将被重启,kubelet 将继续每隔 10 秒运行一次这种探测。
除了存活探针,这个配置还包括一个就绪探针, kubelet 会在容器启动 15 秒后运行第一次就绪探测, 与存活探测类似,就绪探测会尝试连接 goproxy
容器的 8080 端口。 如果就绪探测失败,Pod 将被标记为未就绪,且不会接收来自任何服务的流量。
15 秒之后,通过查看 Pod 事件来检测存活探针:
[root@k8s-master-1 probe]# kubectl describe pod goproxy
配置就绪探针
就绪探针的配置和存活探针的配置相似,唯一区别就是要使用 readinessProbe
字段,而不是 livenessProbe
字段。
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
HTTP 和 TCP 的就绪探针配置也和存活探针的配置完全相同。
就绪和存活探测可以在同一个容器上并行使用。 两者共同使用,可以确保流量不会发给还未就绪的容器,当这些探测失败时容器会被重新启动。
配置启动探针
直接使用命名端口进行 HTTP 或 TCP 检测:
ports:
- name: liveness-port
containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
一般来说,需要使用相同的命令来设置启动探测;
针对 HTTP 或 TCP 检测,可以通过将 failureThreshold * periodSeconds
参数设置为足够长的时间来应对最差情况下的启动时间。
使用启动探针保护,例如:
ports:
- name: liveness-port
containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
在启动探测的保护下,应用将会有最多 5 分钟(30 * 10 = 300s)的时间来完成其启动过程;
一旦启动探测成功一次,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应, 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 restartPolicy
来执行进一步处置。
探针的配置字段
initialDelaySeconds:
容器启动后要等待多少秒后才启动启动、存活和就绪探针, 如果定义了启动探针,则存活探针和就绪探针的延迟将在启动探针已成功之后才开始计算, 如果 periodSeconds 的值大于 initialDelaySeconds,则 initialDelaySeconds 将被忽略,默认是 0 秒,最小值是 0。
periodSeconds:
执行探测的时间间隔(单位是秒),默认是 10 秒,最小值是 1。
timeoutSeconds:
探测的超时后等待多少秒,默认值是 1 秒,最小值是 1。
successThreshold:探针在失败后,被视为成功的最小连续成功数,默认值是 1, 存活和启动探测的这个值必须是 1,最小值是 1。
failureThreshold:
探针连续失败了 failureThreshold 次之后, Kubernetes 认为总体上检查已失败(Unready、Unhealthy、Pending、Failed、Terminated)。默认值为 3,最小值为 1, 对于启动探针或存活探针而言,如果至少有 failureThreshold 个探针已失败, Kubernetes 会将容器视为不健康并为这个特定的容器触发重启操作, kubelet 遵循该容器的 terminationGracePeriodSeconds 设置,对于失败的就绪探针,kubelet 继续运行检查失败的容器,并继续运行更多探针; 因为检查失败,kubelet 将 Pod 的 Ready 状况 设置为 false。
terminationGracePeriodSeconds:
为 kubelet 配置从为失败的容器触发终止操作到强制容器运行时停止该容器之前等待的宽限时长, 默认值是继承 Pod 级别的 terminationGracePeriodSeconds 值(如果不设置则为 30 秒),最小值为 1。