1. 探针介绍
谈探针之前,先来说说Pod。
在k8s中,Pod是最小的计算单元,一个Pod代表集群中运行的一个进程。Pod内部可以封装一个容器,也可以封装多个容器,在节点上,Pod和Pod之间是相互独立的。当创建一个Pod的资源对象的时候,先创建一个pause容器,此容器会帮助Pod创建共享网卡、共享存储卷,网卡和数据卷都是Pod内部容器共享的资源。
k8s为什么这样设计Pod和特殊组成结构呐?
原因一:在一组容器作为一个单元的情况下,难以对整个的容器简单地进行判断以及有效的进行行动。比如,一个容器死了,此时是算整体挂了么?那么引入与业务无关的pause容器作为Pod的根容器,以它的状态代表着整个容器组的状态,这样就可以解决该问题。
原因二:Pod里的多个业务容器共享pause容器的IP,共享pause容器挂载的volume,这样简化了业务容器之间的通信问题,也解决了容器之间的文件共享问题。
再来,我们看看Pod的常见状态:
Pending:挂起,在创建Pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件。已经创建了但是没有适合它运行的节点叫做挂起,这其中包含集群为容器创建网络,或者下载镜像的过程。
Running:Pod内所有的容器都已经被创建,且至少一个容器正在处于运行状态、正在启动状态或者重启状态。
Succeeded:Pod中容器都执行成功后退出,而且不处于重启的容器。
Failed:Pod中容器都已退出,然而至少另有一个容器退出时为掉败情况。
Unknown:未知状态,就是某种原因无法获取Pod状态。
之前说了Pod,那么在运行期间,可能因为某种意外情况致使程序挂掉,那么如何来监控容器状态的稳定性,保证服务在运行期间不会发生问题,即使发生了问题也可以进行重启等机制,就成了非常重要的事情,那么,k8s就有探针机制。
1.1 livenessProbe
存活性探针,用于判断容器是否存活(running状态),如果livenessProbe探针探测到容器不健康,则kubelet杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含livenessProbe探针,则kubelet认为该容器的livenessProbe探针返回的值永远是“Success”。
1.2 readinessProbe
就绪性探针,用于判断容器是否启动完成(ready状态),可以接收请求。如果readinessProbe探针检测到失败,则Pod的状态被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的Endpoint。
1.3 startupProbe
启动探针,k8s 1.16版本后新加的探针方式,主要解决在慢启动程序或者复杂程序中livenessProbe、readinessProbe探针无法较好的判断程序是否启动、是否存活,进而引入startupProbe探针,为livenessProbe、readinessProbe探针服务。如果三个探针同时存在,则先执行startupProbe探针,其他两个探针将会被暂时禁用,直到startupProbe一次探测成功,其他2个探针才启动,如果startupProbe探针失败,kubelet将杀死容器,并根据restartPolicy重启策略来判断容器是否要进行重启操作。
2. 查看探针
查看livenessProbe
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe
KIND: Pod
VERSION: v1
RESOURCE: livenessProbe <Object>
DESCRIPTION:
Periodic probe of container liveness. Container will be restarted if the
probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
Probe describes a health check to be performed against a container to
determine whether it is alive or ready to receive traffic.
FIELDS:
exec <Object>
One and only one of the following should be specified. Exec specifies the
action to take.
failureThreshold <integer>
Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
httpGet <Object>
HTTPGet specifies the http request to perform.
initialDelaySeconds <integer>
Number of seconds after the container has started before liveness probes
are initiated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
periodSeconds <integer>
How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
successThreshold <integer>
Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness and startup.
Minimum value is 1.
tcpSocket <Object>
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
terminationGracePeriodSeconds <integer>
Optional duration in seconds the pod needs to terminate gracefully upon
probe failure. The grace period is the duration in seconds after the
processes running in the pod are sent a termination signal and the time
when the processes are forcibly halted with a kill signal. Set this value
longer than the expected cleanup time for your process. If this value is
nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this
value overrides the value provided by the pod spec. Value must be
non-negative integer. The value zero indicates stop immediately via the
kill signal (no opportunity to shut down). This is a beta field and
requires enabling ProbeTerminationGracePeriod feature gate. Minimum value
is 1. spec.terminationGracePeriodSeconds is used if unset.
timeoutSeconds <integer>
Number of seconds after which the probe times out. Defaults to 1 second.
Minimum value is 1. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
参数简介
initialDelaySeconds:容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认是 0 秒,最小值是 0。
periodSeconds:执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。
timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。
successThreshold:探测器在失败后,被视为成功的最小连续成功数。默认值是 1。存活探测的这个值必须是 1。最小值是 1。
failureThreshold:当 Pod 启动了并且探测到失败,Kubernetes 的重试次数。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
HTTP探针可以在 httpGet 上配置额外的字段:
host:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。
scheme:用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 HTTP。
path:访问 HTTP 服务的路径。
httpHeaders:请求中自定义的 HTTP 头。HTTP 头字段允许重复。
port:访问容器的端口号或者端口名。如果数字必须在 1 ~ 65535 之间。
ReadinessProbe、startupProbe各项参数解释同上面的livenessProbe
3. 探针示例
livenessProbe探针示例
3.1 通过exec方式做健康探测
[root@k8s-master test]# cat liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
labels:
app: liveness
spec:
containers:
- name: liveness
image: busybox
args: #创建测试探针探测的文件
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
initialDelaySeconds: 10 #延迟检测时间
periodSeconds: 5 #检测时间间隔
exec: #使用命令检查
command: #指令,类似于运行命令sh
- cat #sh 后的第一个内容,直到需要输入空格,变成下一行
- /tmp/healthy #由于不能输入空格,需要另外声明,结果为sh cat"空格"/tmp/healthy
# 解释整体意思:
容器在初始化后,执行(/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600")首先创建一个 /tmp/healthy 文件,然后执行睡眠命令,睡眠 30 秒,到时间后执行删除 /tmp/healthy 文件命令。而设置的存活探针检检测方式为执行 shell 命令,用 cat 命令输出 healthy 文件的内容,如果能成功执行这条命令一次(默认successThreshold:1),存活探针就认为探测成功,由于没有配置(failureThreshold、timeoutSeconds),所以执行(cat /tmp/healthy)并只等待1s,如果1s内执行后返回失败,探测失败。在前 30 秒内,由于文件存在,所以存活探针探测时执行 cat /tmp/healthy 命令成功执行。30 秒后 healthy 文件被删除,所以执行命令失败,Kubernetes 会根据 Pod 设置的重启策略来判断,是否重启 Pod。
3.2 通过HTTP方式做健康探测
httpGet探测方式有如下可选的控制字段:
scheme: 用于连接host的协议,默认为HTTP。
host:要连接的主机名,默认为Pod IP,可以在http request head中设置host头部。
port:容器上要访问端口号或名称。
path:http服务器上的访问URI。
httpHeaders:自定义HTTP请求headers,HTTP允许重复headers。
[root@k8s-master test]# cat liveness-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
labels:
test: liveness
spec:
containers:
- name: liveness
image: test/springboot-helloworld:0.0.1
livenessProbe:
failureThreshold: 5 #检测失败5次表示未就绪
initialDelaySeconds: 20 #延迟加载时间
periodSeconds: 10 #重试时间间隔
timeoutSeconds: 5 #超时时间设置
successThreshold: 2 #检查成功为2次表示就绪
httpGet:
scheme: HTTP
port: 8081
path: /actuator/health
# 解释整体意思:
上面 Pod 中启动的容器是一个 SpringBoot 应用,其中引用了 Actuator 组件,提供了 /actuator/health 健康检查地址,在pod启动后,初始化等待20s后,livenessProbe开始工作,去请求HTTP://podIP:8081/actuator/health 接口,类似于curl -I HTTP://podIP:8081/actuator/health接口,考虑到请求会有延迟(curl -I后一直出现假死状态),所以给这次请求操作一直持续5s,如果5s内访问返回数值在>=200且<=400代表第一次检测success,如果是其他的数值,或者5s后还是假死状态,执行类似(ctrl+c)中断,并反回failure失败。等待10s后,再一次的去请求HTTP://podIP:8081/actuator/health接口。如果有连续的2次都是success,代表无问题。如果期间有连续的5次都是failure,代表有问题,直接重启pod,此操作会伴随pod的整个生命周期
3.3 通过TCP方式健康探测
[root@k8s-master test]# cat liveness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcp
labels:
app: liveness
spec:
containers:
- name: liveness
image: nginx
livenessProbe:
initialDelaySeconds: 15
periodSeconds: 20
tcpSocket:
port: 80
# 解释整体意思:
TCP 检查方式和 HTTP 检查方式非常相似,在容器启动 initialDelaySeconds 参数设定的时间后,kubelet 将发送第一个 livenessProbe 探针,尝试连接容器的 80 端口,类似于telnet 80端口,如果连接失败则将杀死 Pod 重启容器。
参考链接:https://www.akiraka.net/kubernetes/855.html
https://blog.csdn.net/qq_42642159/article/details/122719094
https://blog.csdn.net/m0_45406092/article/details/118997434
https://blog.csdn.net/Jerry00713/article/details/123894868