Kubernetes 健康检查的两种机制:Liveness 探测和 Readiness 探测,并实践了健康检查在 Scale Up 和 Rolling Update 场景中的应用。
kubelet使用启动探针来了解何时启动Container应用程序。如果配置了这样的探针,它将禁用活动性和就绪性检查,直到成功为止,以确保这些探针不会干扰应用程序的启动。这可用于对启动缓慢的容器进行活动检查,避免它们在启动和运行之前被kubelet杀死。
定义活动命令exec
在本练习中,您将创建一个Pod,该Pod可基于k8s.gcr.io/busybox
图像运行一个Container 。这是Pod的配置文件:
pods/probe/exec-liveness.yaml apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-exec spec: containers: - name: liveness image: k8s.gcr.io/busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
在配置文件中,您可以看到Pod具有单个Container。该periodSeconds
字段指定kubelet应该每5秒执行一次活动性探测。该initialDelaySeconds
字段告诉kubelet在执行第一个探测之前应等待5秒。为了执行探测,kubelet cat /tmp/healthy
在容器中执行命令。如果命令成功执行,则返回0,并且kubelet认为Container处于活动状态且健康。如果命令返回非零值,则kubelet将杀死Container并重新启动它。
在容器寿命的前30秒中,有一个/tmp/healthy
文件。因此,在前30秒内,该命令cat /tmp/healthy
将返回成功代码。30秒后,cat /tmp/healthy
返回失败代码。
在30秒内,查看Pod事件:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
35秒后,再次查看Pod事件:在输出的底部,有消息指示活动性探针已失败,并且容器已被杀死并重新创建。
FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e 2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
再等待30秒,并验证容器已重新启动:
kubectl get pod liveness-exec NAME READY STATUS RESTARTS AGE liveness-exec 1/1 Running 1 1m
定义活动HTTP请求
另一种活动性探针使用HTTP GET请求。这是基于k8s.gcr.io/liveness 映像运行容器的Pod的配置文件。
pods/probe/http-liveness.yaml apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec: containers: - name: liveness image: k8s.gcr.io/liveness args: - /server livenessProbe: httpGet: path: /healthz port: 8080 httpHeaders: - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3
在配置文件中,您可以看到Pod具有单个Container。该periodSeconds
字段指定kubelet应该每3秒执行一次活动性探测。该initialDelaySeconds
字段告诉kubelet在执行第一个探测之前应等待3秒。为了执行探测,kubelet将HTTP GET请求发送到在Container中运行并在端口8080上侦听的服务器。如果服务器/healthz
路径的处理程序返回成功代码,则kubelet认为Container处于活动状态且运行状况良好。如果处理程序返回失败代码,则kubelet将杀死Container并重新启动它。
任何大于或等于200且小于400的代码均表示成功。其他任何代码均指示失败。
您可以在server.go中查看服务器的源代码 。
在Container /healthz
处于活动状态的前10秒钟中,处理程序返回状态200。此后,处理程序返回状态500。
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { duration := time.Now().Sub(started) if duration.Seconds() > 10 { w.WriteHeader(500) w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds()))) } else { w.WriteHeader(200) w.Write([]byte("ok")) } })
容器启动后三秒钟,kubelet将开始执行运行状况检查。因此,前几次健康检查将成功。但是10秒钟后,运行状况检查将失败,并且kubelet将终止并重新启动Container。
定义TCP liveness探针
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
定义 readiness probes
有时,应用程序暂时无法为流量提供服务。例如,应用程序可能需要在启动过程中加载大数据或配置文件,或者在启动后依赖于外部服务。在这种情况下,您不想杀死应用程序,但也不想发送请求。Kubernetes提供了准备就绪探针以检测和缓解这些情况。带有容器的容器报告其容器尚未准备就绪,无法通过Kubernetes Services接收流量。
readiness的配置与liveness类似。唯一的区别是您使用readinessProbe
字段而不是livenessProbe
字段。
readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
HTTP和TCP就绪性探针的配置也与活动性探针相同。
readiness和liveness可以并行用于同一容器。同时使用这两者可以确保流量不会到达尚未准备就绪的容器,并且可以确保容器在发生故障时重新启动。