Probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断,kubelet 调用由容器实现的 Handler (处理程序)。
三种类型的处理程序
探针检查结果分为3种情况:
Success
(成功):容器通过了诊断。Failure
(失败):容器未通过诊断。Unknown
(未知):诊断失败,因此不会采取任何行动。
三种探针
-
livenessProbe
:指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为Success
。 -
readinessProbe
:指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为Failure
。 如果容器不提供就绪态探针,则默认状态为Success
。 -
startupProbe
: 指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet
将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为Success
。
重启策略
当pod中一个container处于退出状态(Exited)时,kubelet会根据Pod Spec中设置restartPolicy进行相应操作,重启的策略分别如下:
Always: 默认的重启策略,只要有一个container处于Exited时,即会重启
OnFailure:container退出状态不为0时,即会重启。
Never: 从不重启。
需要重点说明的是:
一个pod设置重启策略,适用于pod中全部container。
处于退出状态的容器由 kubelet 以五分钟为上限的指数衰减延迟(10秒,20秒,40秒…)重新启动,并在container重启成功十分钟后会重置该值。
定义存活命令
许多长时间运行的应用程序最终会过渡到断开的状态,除非重新启动,否则无法恢复。 Kubernetes 提供了存活探测器来发现并补救这种情况。
在这篇练习中,你会创建一个 Pod,其中运行一个基于 k8s.gcr.io/busybox
镜像的容器。 下面是这个 Pod 的配置文件。
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:
kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
在 30 秒内,查看 Pod 的事件:
kubectl describe pod liveness-exec
输出结果表明还没有存活探测器失败:
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 的事件:
kubectl describe pod liveness-exec
在输出结果的最下面,有信息显示存活探测器失败了,这个容器被杀死并且被重建了。
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
输出结果显示 RESTARTS
的值增加了 1。
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
使用启动探测器保护慢启动容器
有时候,会有一些现有的应用程序在启动时需要较多的初始化时间。 要不影响对引起探测死锁的快速响应,这种情况下,设置存活探测参数是要技巧的。 技巧就是使用一个命令来设置启动探测,针对HTTP 或者 TCP 检测,可以通过设置 failureThreshold * periodSeconds
参数来保证有足够长的时间应对糟糕情况下的启动时间。
所以,前面的例子就变成了:
ports: - name: liveness-port containerPort: 8080 hostPort: 8080 livenessProbe: httpGet: path: /healthz port: liveness-port failureThreshold: 1 periodSeconds: 10 startupProbe: httpGet: path: /healthz port: liveness-port failureThreshold: 30 periodSeconds: 10
定义就绪探测器
有时候,应用程序会暂时性的不能提供通信服务。 例如,应用程序在启动时可能需要加载很大的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用程序,也不想给它发送请求。 Kubernetes 提供了就绪探测器来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。
说明: 就绪探测器在容器的整个生命周期中保持运行状态
就绪探测器的配置和存活探测器的配置相似。 唯一区别就是要使用 readinessProbe
字段,而不是 livenessProbe
字段。
readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
HTTP 和 TCP 的就绪探测器配置也和存活探测器的配置一样的。
就绪和存活探测可以在同一个容器上并行使用。 两者都用可以确保流量不会发给还没有准备好的容器,并且容器会在它们失败的时候被重新启动。
配置探测器
Probe 有很多配置字段,可以使用这些字段精确的控制存活和就绪检测的行为:
initialDelaySeconds
:容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认是 0 秒,最小值是 0。periodSeconds
:执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。timeoutSeconds
:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。successThreshold
:探测器在失败后,被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。failureThreshold
:当探测失败时,Kubernetes 的重试次数。 存活探测情况下的放弃就意味着重新启动容器。 就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
HTTP探测请求
HTTP Probes 可以在 httpGet
上配置额外的字段:
host
:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。scheme
:用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 HTTP。path
:访问 HTTP 服务的路径。默认值为 "/"。httpHeaders
:请求中自定义的 HTTP 头。HTTP 头字段允许重复。port
:访问容器的端口号或者端口名。如果数字必须在 1 ~ 65535 之间。
livenessProbe: httpGet: path: /healthz port: 8080 httpHeaders: - name: X-Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3
TCP探测请求
对于一次 TCP 探测,kubelet 在节点上(不是在 Pod 里面)建立探测连接, 这意味着你不能在 host
参数上配置服务名称,因为 kubelet 不能解析服务名称
tcpSocket: port: 8080 initialDelaySeconds: 15 periodSeconds: 20
exec探测请求
通过执行shell命令的方式,判断退出状态码是否是0
exec: command: - cat - /tmp/healthy
转载自:https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/