Docker 与 K8S学习笔记(二十一)—— Pod生命周期、重启策略与健康检查
Pod在整个生命周期中被系统标示为各种状态,熟悉Pod的各种状态对于理解Pod的调度策略、重启策略很有必要。
一、Pod生命周期
Pod的所处阶段信息保存在PodStatus.Phase,Phase有如下几种值:
-
Pending: API Server已经创建该Pod,但一个或多个容器还没有被创建,包括通过网络下载镜像的过程。
-
Running: Pod中的所有容器都已经被创建且已经调度到 Node 上面,但至少有一个容器还在运行或者正在启动。
-
Succeeded: Pod 调度到 Node 上面后均成功运行结束,并且不会重启。
-
Failed: Pod中的所有容器都被终止了,但至少有一个容器退出失败(即退出码不为 0 或者被系统终止)。
-
Unknonwn: 状态未知,因为一些原因Pod无法被正常获取,通常是由于 apiserver 无法与 kubelet 通信导致。
Pod的生命周期示意图如下:
大家可以看到,Phase记录的是Pod在其生命周期中的简单宏观概述。该阶段并不是对容器或Pod的综合汇总,也不是为了作为综合状态机,我们举个例子理解一下:
$ sudo kubectl create -f webapp_pod.yaml pod/webapp created $ sudo kubectl get pod NAME READY STATUS RESTARTS AGE webapp 0/2 ContainerCreating 0 3s $ sudo kubectl get pod webapp -o jsonpath="{.status.phase}" Pending
我们可以看到当创建Pod时,我们通过get pod能看到Pod状态为ContainerCreating,通过phase看到Pod所处的阶段是Pending,所以Phase描述Pod更为宏观的状态。
二、Pod重启策略
Pod的重启策略应用与Pod内所有容器,并且仅在Pod所处的Node上由kubelet进行判断和操作,当某个容器异常退出或者健康检查失败时,kubelet将根据RestartPolicy进行对应操作。
Pod重启策略如下:
-
Always:当容器退出时,无论失败与否都重启
-
OnFailure:当容器终止运行且退出码不为零,则重启
-
Never:无论容器状态如何,都不重启
Pod重启策略与控制方式息息相关,可管理Pod的控制器有:RC、Job、DaemonSet、kubelet(静态Pod)等,每种控制器对Pod的重启策略要求如下:
-
RC和DaemonSet:必须设置为Always,确保容器持续运行
-
Job:可设置为OnFailure或Never,确保容器执行完成后释放资源不再重启
-
kubelet:不论设置什么样的重启策略,其在Pod失效时都会自动重启
结合Pod的生命周期和重启策略,我们可得出下表中Pod状态切换过程:
Pod容器数 | Pod当前阶段 | 发生事件 | Pod不同重启策略下的结果状态 | ||
Always | OnFailure | Never | |||
1个容器 | Running | 容器正常退出 | Running | Successed | Successed |
1个容器 | Running | 容器退出失败 | Running | Running | Failed |
2个容器 | Running | 1个容器退出失败 | Running | Running | Running |
2个容器 | Running | 容器被OOM杀掉 | Running | Running | Failed |
三、Pod健康检查
Kubernetes对Pod的健康检查可通过三类探针来完成:
-
LivenessProbe:探测容器是否正在运行。如果探测容器不健康,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定后续操作。如果容器不包含此探针, 则默认状态为 Success。
-
ReadinessProbe:探测容器是否准备好为请求提供服务。如果就探测失败, 系统将从与 Pod 匹配的所有服务的EndPoint列表中删除该 Pod 的 IP 地址。如果容器不包含此探针,则默认状态为 Success。
-
StartupProbe: 探测容器中的应用是否已经启动。如果提供了此探针,则所有其他探针都会被禁用,直到此探针成功为止。如果探测失败,kubelet 将杀死容器,然后容器按照其重启策略进行后续操作。如果容器不包含此探测,则默认状态为 Success。
以上探针均可配置以下三种实现方式:
-
ExecAction:在容器内执行指定命令。如果命令退出码为 0 则认为诊断成功。
-
TCPSockerAction:对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。
-
HTTPGetAction:对容器的 IP 地址上指定端口和URL执行 Get 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
-
Success(成功):容器通过了诊断。
-
Failure(失败):容器未通过诊断。
-
Unknown(未知):诊断失败,因此不会采取任何行动。