一、`restartPolicy` 与退出码(exit code)的关系
Kubernetes 提供三种重启策略,其中最高粒度其实是在 Pod 级别,并不是为单独的容器设定的。不同策略下对退出码的处理逻辑如下:
| 策略名称 | 退出码 = 0 | 退出码 ≠ 0(非0) | 说明 |
|---|---|---|---|
| Always | 重启 | 重启 | 无条件重启容器 |
| OnFailure | 不重启 | 重启 | 只有非正常退出时才重启 |
| Never | 不重启 | 不重启 | 不管退出码如何都不自动重启 |
- Always:无论容器正常退出(exit code = 0)还是异常退出(exit code ≠ 0),Kubelet 都会尝试重启该容器。
- OnFailure:只有当退出码非零时才会重启;若退出码是 0(成功结束),则不会重启。
- Never:无论退出码为多少,都不会重启。(gremlin.com, komodor.com)
二、退出码本身的含义
退出码不仅指示是否成功,还能反映运行中出现的具体错误类型:
- 退出码为 0:代表容器正常结束,无错误。
- 非零退出码(1–128):通常表示应用逻辑错误、缺少依赖、脚本报错等。(datree.io)
三、指数退避机制(Exponential Back-off)
对于使用 Always 或 OnFailure 策略的重启行为,Kubelet 会启用指数退避机制来避免频繁重启,减少资源浪费与日志疯狂输出:
- 重启间隔时间依次增长:10 秒 → 20 秒 → 40 秒 …,最大可延迟到 5 分钟。
- 如果容器连续稳定运行超过 10 分钟,退避计时器会重置。(gremlin.com)
例如出现 CrashLoopBackOff,就表示正在进行这种重启与等待的循环状态。(sysdig.com)
四、实际操作验证(模拟示例)
你提到的实验步骤和效果描述是准确的,下面结合官方示例和文档来佐证:
OnFailure 策略 最典型用例是批处理任务。若任务成功(exit code = 0),不会重启;若失败(exit code ≠ 0),Kubelet 会依据策略尝试重启。(medium.com)
可通过如下 Pod YAML 验证行为:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: onfailure-demo
spec:
restartPolicy: OnFailure
containers:- name: busybox-fail
image: busybox
command: [“sh”, “-c”, “exit 1”]
```
该 Pod 会因 `exit 1` 而重启。
- name: busybox-fail
若改为 `exit 0`,则不会重启,Pod 状态变为 Completed。(discuss.kubernetes.io, medium.com)