一、`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)

对于使用 AlwaysOnFailure 策略的重启行为,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` 而重启。

  • 若改为 `exit 0`,则不会重启,Pod 状态变为 Completed。(discuss.kubernetes.io, medium.com)