💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ### **Pod的三种重启策略** 在Pod的spec中有一个restartPolicy字段,如下: ``` apiVersion: v1 kind: Pod metadata: name: xxx spec: restartPolicy: Always ... ``` restartPolicy的值有三个:Always、OnFailure、Never;默认值为Always。 **注意:虽然restartPolicy字段是Pod的配置,但是其实是作用于Pod的Container,换句话说,不应该叫Pod的重启策略,而是叫Container的重启策略;Pod中的所有Container都适用于这个策略。** 三种策略的区别在于(参考Reference 2的回答): * Always:只要Container退出,就重启,即使用它的退出码为0(即成功退出) * OnFailure:如果Container的退出码不是0(即失败退出),就重启 * Never:Container退出后永不重启 所谓Container的退出码,就是Container中进程号为1的进程的退出码。每个进程退出时都有一个退出码,我们常见的提示`exit 0`表示退出码为0(即成功退出)。举个例子:shell命令`cat /tmp/file`,如果文件`/tmp/file`存在,则该命令(进程)的退出码为0。 ### **重启Container** 上面谈到当Container退出后,Container可能会被重启,那么Container是如何被重启的呢?是kubelet调用类似于docker start的API拉起?还是重新创建一个docker容器? 答案是,kubelet会重新创建一个docker容器。 我们给一个例子,创建一个如下的Pod,这个Pod中有两个Container,其中`linzhe`这个Container在启动后60秒就会退出(退出码为0),`shizhu`这个Container则会一直运行 ``` apiVersion: v1 kind: Pod metadata: name: peng spec: restartPolicy: Always containers: - name: linzhe image: tomcat:8 command: - /bin/sh - -c - sleep 60 - name: shizhu image: tomcat:8 ``` 接下来我们创建这个Pod,然后观察`linzhe`这个Container的docker名字与ID,发现名字为`k8s_linzhe_peng_default_2cf74016-f80f-47b8-bd77-f7c96a02fa3b_0`,ID为`557818a3da5c` ``` $ docker ps | grep linzhe 557818a3da5c 3d793e2e777b "/bin/sh -c 'sleep 6…" 8 seconds ago Up 6 seconds k8s_linzhe_peng_default_2cf74016-f80f-47b8-bd77-f7c96a02fa3b_0 ``` 再过一分钟,我们再看这个Container的名字和ID,发现名字为`k8s_linzhe_peng_default_2cf74016-f80f-47b8-bd77-f7c96a02fa3b_1`,ID为`7ec6c5d33dd7`。这说明,重启后已经不是同一个docker容器了。 ``` $ docker ps | grep linzhe 7ec6c5d33dd7 3d793e2e777b "/bin/sh -c 'sleep 6…" 37 seconds ago Up 35 seconds k8s_linzhe_peng_default_2cf74016-f80f-47b8-bd77-f7c96a02fa3b_1 ``` 如果我们细心的会发现,docker容器的名字其实是有规则的,为`k8s_<ContainerName_In_Pod>_<PodName>_<Namespace>_<PodID>_<Index>`;其中最后一个`<Index>`一开始为0,每重启一次就会递增1。 如果同时我们查看Pod的yaml文件,会发现这个Container的restartCount为1 ``` $ kubectl get pod peng -o yaml ... status: ... containerStatuses: - containerID: docker://7ec6c5d33dd7ad6f04824a37a4bb02639ecc71e0e5921bc53dbc2e610b2381fc ... name: linzhe ready: false restartCount: 1 started: false ``` 如果再等几分钟,查看Pod的状态,会变成`CrashLoopBackOff` ``` $ kubectl get pod peng NAME READY STATUS RESTARTS AGE peng 1/2 CrashLoopBackOff 5 11m ``` ### **最佳实践** 一般Pod是通过工作负载去管理的,在五种工作负载中,一般建议:Deployment、StatefulSet、DaemonSet设置为Always;Job与CronJob设置为OnFailure或Never ### **Reference** * https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy * https://stackoverflow.com/questions/40530946/what-is-the-difference-between-always-and-on-failure-for-kubernetes-restart-poli