Pod生命周期和健康检查
一、Pod生命周期和重启策略:
Pod在整个生命周期中被系统定义为各种状态,熟悉Pod的各种状态 对于理解如何设置Pod的调度策略、重启策略是很有必要的
Pod的几种状态如下所示:
| 状态值 | 描述 |
| Pending | Apiserver已经创建该Pod,但是pod内还要一个或多个容器镜像没有创建,包括正在下载镜像的过程 |
| Running | Pod所有容器已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态 |
| Succeeded | Pod内所有容器均成功执行后退出,且不会再重启 |
| Failed | Pod内容器均已成功退出,但至少有一个容器退出为失败状态 |
| Unknown | 由于某种原因无法获取pod状态,可能是网络不通 |
| Blocked | Pod处于阻塞状态无法正常运行,资源不足或无法访问,或Pod的调度可能遇到了问题 |
Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某个容器异常退出或者健康检查(详见下节)失败时,kubelet将根据RestartPolicy的设置来进行相应的操作。
Pod的重启策略包括Always、OnFailure和Never,默认值为Always,说明如下:
- Always:当容器失效时,由kubelet自动重启该容器。
- OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
- Never:不论容器运行状态如何,kubelet都不会重启该容器
kubelet重启失效容器的时间间隔以sync-frequency乘以2n来计算,例 如1、2、4、8倍等,最长延时5min,并且在成功重启后的10min后重置该时间
Pod的重启策略与控制方式息息相关,当前可用于管理Pod的控制器 包括ReplicationController、Job、DaemonSet及直接通过kubelet管理(静 态Pod)。每种控制器对Pod的重启策略要求如下:
- RC和DaemonSet:必须设置为Always,需要保证该容器持续运行。
- Job:OnFailure或Never,确保容器执行完成后不再重启
- kubelet:在Pod失效时自动重启它,不论将RestartPolicy设置为什么值,也不会对Pod进行健康检查(静态pod)
| pod状态 | pod状态 | pod状态 | |||
| Pod包含容器数 | Pod当前状态 | 事件 | Always | OnFailure | Never |
| 包含1个容器 | Running | 容器退出成功 | Running | Succeeded | Succeeded |
| 包含1个容器 | Running | 容器退出失败 | Running | Running | Failed |
| 包含2个容器 | Running | 1个容器退出失败 | Running | Running | Running |
| 包含2个容器 | Running | 容器被oom杀掉 | Running | Running | Failed |
二、Pod健康检查:
Kubernetes 对 Pod 的健康状态可以通过三类探针来检查: LivenessProbe 和ReadinessProbe以及StartupProbe,其中最主要的探针是 LivenessProbe 和ReadinessProbe ,kubelet定期执行这两类探针来诊断容器的健康状况。
1、 LivenessProbe探针:用于判断容器是否存活(Running状 态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含 LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是Success。
2、 ReadinessProbe探针:用于判断容器服务是否可用(Ready状 态),达到Ready状态的Pod才可以接收请求。对于被Service管理的 Pod,Service与Pod Endpoint的关联关系也将基于Pod是否Ready进行设置。如果在运行过程中Ready状态变为False,则系统自动将其从Service 的后端Endpoint列表中隔离出去,后续再把恢复到Ready状态的Pod加回后端Endpoint列表。这样就能保证客户端在访问Service时不会被转发到服务不可用的Pod实例上。
3、StartupProbe探针:某些应用会遇到启动比较慢的情况,例如应用程序启动时需要与远程服务器建立网络连接,或者遇到网络访问较慢等情况时,会造成容器启动缓慢,此时ReadinessProbe就不适用了,因为这属于“有且仅有一次”的超长延时,可以通过StartupProbe探针解决该问题。
注:三种检查方式同时只能使用一种
以上探针均可配置以下三种实现方式:
1、ExecAction:在容器内部运行一个命令,如果该命令的返回码为0,则表明容器健康。
下面pod中,在容器生命周期的最初60s内,会创建一个healthy文件,因此这60s内执行cat会返回一个成功的状态码,60s后,文件将删除,然后cat返回失败状态码,其中,periodSeconds规定kubelet每隔10s执行一次liveness probe,initialDelaySeconds 告诉kubelet 在第一次执行 probe 之前要的等待30秒钟(因为有些容器可能启动比较慢,需要拉镜像,因此需要等待久一点,以免误判) ,如图:

2、TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,如果能够建立TCP连接,则表明容器健康
下面pod中,通过与容器内的8080端口建立tcp连接来进行健康检查,如果8080端口不通,那么此Pod将被杀掉然后重启,如图:

3、HTTPGetAction:通过容器的IP地址、端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康。
下面例子表示探测nginx容器,路径就是nginx的默认访问页面地址,如图:

创建pod后观察重启次数,可以看到重启次数为0 ,如图:

现在进入容器,删除默认的访问页面index.html,然后再观察重启次数,命令如下:
kubectl exec -it liveness-httpget-pod -- rm -f /usr/share/nginx/html/index.html
观察重启次数为1,如图:

描述信息里可以看到提示找不到文件,报错404,如图:

重启后的Pod,内部会重新生成index.html,因此再次健康检查将成功
对 于 每 种 探 测 方 式 , 都 需 要 设 置 initialDelaySeconds 和timeoutSeconds两个参数,它们的含义分别如下:
- initialDelaySeconds:启动容器后进行首次健康检查的等待时间,单位为s。
- timeoutSeconds:健康检查发送请求后等待响应的超时时间单位为s。当超时发生时,kubelet会认为容器已经无法提供服务,将会重启该容器
- periodSeconds:规定kubelet每隔一定时间执行一次liveness probe,单位是s
- successThreshold: 检查成功几次后表示就绪,比如设置为2,则为2次成功后就绪
- failureThreshold: 检查失败几次后表示未就绪,如设置1,则为检查失败1次后表示未就绪
注:生产环境建议使用httpGet实现接口级健康检查


