# Pod 生命周期和重启策略

## Pod 的生命周期

Pod 在运行时会有不同的状态，Pod 的状态信息保存在 **PodStatus** 对象中，在 PodStatus 中有一个 **Phase** 字段，用于描述 Pod 在其生命周期中的不同状态。

可以使用 Kubernetes 的客户端工具 Kubectl 查看某个 Pod 的 Phase 字段，比如查看 kube-system 命名空间下的 metrics-server 的状态：

```properties
$ kubectl get po -l k8s-app=metrics-server -n kube-system
NAME                              READY   STATUS    RESTARTS       AGE
metrics-server-7775d96dc7-nbzgs   1/1     Running   14 (21m ago)   41h

$ kubectl get po -l k8s-app=metrics-server -n kube-system -o yaml | grep phase
phase: Running
```

Pod 的 Phase 字段只有 <mark style="color:blue;">**Pending**</mark>、<mark style="color:blue;">**Running**</mark>、<mark style="color:blue;">**Succeeded**</mark>、<mark style="color:blue;">**Failed**</mark>、<mark style="color:blue;">**Unknown**</mark> 5 种状态。

<table><thead><tr><th width="209">取值</th><th>描述</th></tr></thead><tbody><tr><td><mark style="color:blue;"><strong>Pending（挂起）</strong></mark></td><td><ul><li>Pod 已被 Kubernetes 系统接收，但仍有一个或多个容器未被创建</li><li>可以通过 kubectl describe 查看处于  Pending 状态的原因</li></ul></td></tr><tr><td><mark style="color:blue;"><strong>Running（运行中）</strong></mark></td><td><ul><li>Pod 已经被绑定到一个节点上，并且所有的容器都已经被创建，而且至少有一个是运行状态、正在启动或者重启</li><li>可以通过 kubectl logs 查看 Pod 的日志</li></ul></td></tr><tr><td><mark style="color:blue;"><strong>Succeeded（成功）</strong></mark></td><td><ul><li>所有容器执行成功并终止，并且不会再次重启</li><li>可以通过 kubectl logs 查看 Pod 的日志</li></ul></td></tr><tr><td><mark style="color:blue;"><strong>Failed（失败）</strong></mark></td><td><ul><li>所有容器都已终止，并且至少有一个容器以失败的方式终止，也就是说这个容器要么以非零状态退出，要么被系统终止</li><li>可以通过 logs 和 describe 查看 Pod 的日志和状态</li></ul></td></tr><tr><td><mark style="color:blue;"><strong>Unknown（未知）</strong></mark></td><td><ul><li>因为某些原因无法取得 Pod 的状态</li><li>通常是由于通信问题造成的</li></ul></td></tr></tbody></table>

## Pod 重启策略

Pod 的重启策略（RestartPolicy）应用于 Pod 内的所有容器，并且仅在 Pod 所处的 Node 上由 kubelet 进行判断和重启操作。<mark style="color:blue;">**当某个容器异常退出或者健康检查失败时，kubelet 将根据 RestartPolicy 的设置来进行相应的操作。**</mark>

Pod 的重启策略包括 <mark style="color:blue;">**Always**</mark>、<mark style="color:blue;">**OnFailure**</mark> 和 <mark style="color:blue;">**Never**</mark>，**默认值为 Always**。

* <mark style="color:blue;">**Always**</mark>：当容器失效时，由 kubelet 自动重启该容器。
* <mark style="color:blue;">**OnFailure**</mark>：当容器终止运行且退出码不为 0 时，由 kubelet 自动重启该容器。
* <mark style="color:blue;">**Never**</mark>：不论容器运行状态如何，kubelet 都不会重启该容器。

<mark style="color:blue;">**Pod 的重启策略与控制方式息息相关**</mark>，当前可用于管理 Pod 的控制器包括 **ReplicationController**、**Job**、**DaemonSet** 及直接通过 kubelet 管理（静态 Pod）。每种控制器对 Pod 的重启策略要求如下：

* **RC** 和 **DaemonSet**：必须设置为 Always，需要保证该容器持续运行。
* **Job**：**OnFailure** 或 **Never**，确保容器执行完成后不再重启。
* **kubelet**：在 Pod 失效时自动重启它，不论将 RestartPolicy 设置为什么值，也不会对 Pod 进行健康检查。

{% hint style="success" %}
#### <mark style="color:blue;">**kubelet 重启失效容器的时间间隔以 sync-frequency 乘以 2n 来计算**</mark>，例如 1、2、4、8 倍等，最长延时 5min，并且在成功重启后的 10min 后重置该时间。
{% endhint %}

## 字段 Phase 其他取值

<table><thead><tr><th width="239">取值</th><th>说明</th></tr></thead><tbody><tr><td><p><mark style="color:blue;"><strong>ImagePullBackOff</strong></mark></p><p><mark style="color:blue;"><strong>ErrImagePull</strong></mark></p></td><td><p>镜像拉取失败，一般是由于镜像不存在、网络不通或者需要登录认证引起的</p><p>可以使用 describe 命令查看具体原因</p></td></tr><tr><td><mark style="color:blue;"><strong>CrashLoopBackOff</strong></mark></td><td>容器启动失败，可以通过 logs 命令查看具体的原因，一般为启动命令不正确、健康检查不通过等</td></tr><tr><td><mark style="color:blue;"><strong>OOMKilled</strong></mark></td><td><p>容器内存溢出，一般是容器的内存 Limit 设置得过小，或者程序本身有内存溢出</p><p>可以通过 logs 查看程序的启动日志</p></td></tr><tr><td><mark style="color:blue;"><strong>Terminating</strong></mark></td><td>Pod 正在被删除，可以通过 describe 查看状态</td></tr><tr><td><mark style="color:blue;"><strong>SysctlForbidden</strong></mark></td><td><p>Pod 自定义了内核配置，但 kubelet 没有添加内核配置或配置的内核参数不支持</p><p>可以通过 describe 查看具体原因</p></td></tr><tr><td><mark style="color:blue;"><strong>Completed</strong></mark></td><td><p>容器内部主进程退出，一般计划任务执行结束会显示该状态</p><p>此时可以 通过 logs 查看容器日志</p></td></tr><tr><td><mark style="color:blue;"><strong>ContainerCreating</strong></mark></td><td><p>Pod 正在创建，一般为正在下载镜像，或者有配置不当的地方</p><p>可以通过 describe 查看具体原因</p></td></tr></tbody></table>
