1. 概述

在 Kubernetes 中,Pod 内的容器可以通过重启策略(Restart Policy)来控制其行为。这些策略是 Kubernetes 提供的一种自愈机制,用于决定在容器退出时是否需要重启。

不同的重启策略适用于不同类型的容器任务。例如,有些容器需要持续运行(如 Web 服务),而有些容器只需要执行一次任务后退出即可(如 Job)。本文将重点讲解两种常见的重启策略:AlwaysOnFailure,并结合示例说明它们的行为差异。


2. Always 重启策略

Always 是 Kubernetes 中的默认重启策略。如果你创建 Pod 时没有显式指定 restartPolicy,系统会自动将其设为 Always

行为特点:无论容器因何原因退出(成功或失败),都会被重启。

这非常适合那些需要持续运行的容器,例如 Web 服务器、API 服务等。只要容器退出,Kubernetes 就会自动重启它,确保服务不中断。

示例

以下是一个使用 Always 策略的 Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: always-up
  name: always-up
spec:
  containers:
  - image: alpine
    name: always-up
    command: ["sh","-c","sleep 20"]
  restartPolicy: Always

在这个例子中,容器执行 sleep 20 命令后退出,但由于重启策略为 Always,Kubernetes 会在其退出后立即重启它。

验证结果

$ kubectl get po
NAME        READY   STATUS    RESTARTS     AGE
always-up   1/1     Running   1 (4s ago)   25s

通过 kubectl describe 可以看到容器退出状态为 Exit Code 0,但仍然被重启了:

Last State:     Terminated
  Reason:       Completed
  Exit Code:    0

⚠️ 注意: 如果你希望容器执行完任务后不再重启,不要使用 Always 策略。


3. OnFailure 重启策略

OnFailure 策略则更加“理智”,只有当容器以非零退出码退出时(即出错)才会被重启

行为特点:容器正常退出(Exit Code 0)不会触发重启,只有出错时才会尝试重启。

这种策略非常适合一次性任务,比如数据处理、批处理作业等。如果任务执行成功,容器退出,Kubernetes 不会再重启它;但如果任务失败,Kubernetes 会尝试重启容器继续执行。

示例

下面是一个使用 OnFailure 策略的 Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: on-failure
  name: on-failure
spec:
  containers:
  - image: alpine
    name: on-failure
    command: ["sh","-c","sleep 20"]
  restartPolicy: OnFailure

容器执行完 sleep 20 后正常退出,查看状态:

$ kubectl get po
NAME         READY   STATUS      RESTARTS   AGE
on-failure   0/1     Completed   0          94s

此时没有重启记录,因为容器是正常退出的。

引发错误测试

我们修改命令,故意制造一个错误:

command: ["sh","-c","sleeeep 20"]

再次部署后查看状态:

$ kubectl get po
NAME         READY   STATUS             RESTARTS     AGE
on-failure   0/1     CrashLoopBackOff   1 (3s ago)   6s

此时容器因为命令错误退出(Exit Code 127),触发了重启策略,Kubernetes 开始尝试重启。


4. 总结对比

重启策略 容器正常退出(Exit Code 0) 容器异常退出(Exit Code ≠ 0) 适用场景
Always ✅ 重启 ✅ 重启 持续运行的服务(如 Web 服务)
OnFailure ❌ 不重启 ✅ 重启 一次性任务(如 Job、脚本)

5. 实际应用建议

  • ✅ 对于需要持续运行的服务(如 Nginx、Spring Boot 应用等),使用 Always
  • ✅ 对于只需要执行一次的任务(如数据导入、定时脚本等),使用 OnFailure
  • ⚠️ 不要在 Job 控制器中使用 Always 策略,这会导致任务无法正常结束,Job 会一直处于运行状态。

6. 常见踩坑点

  • ❌ 错误地在 Job 中使用 restartPolicy: Always,导致任务永远无法完成。
  • ❌ 误以为 restartPolicy 控制整个 Pod 的生命周期,实际上它只控制 Pod 中的容器行为。
  • ❌ 忽略容器退出码,直接依赖日志判断失败原因,应优先查看 kubectl describe pod 中的 Exit Code

7. 结语

Kubernetes 的重启策略是容器编排中非常基础但又极其关键的一环。合理使用 AlwaysOnFailure,可以让你更好地控制容器行为,提升系统的稳定性和任务执行的可靠性。在实际部署中,务必根据容器任务类型选择合适的策略,避免因策略不当引发的问题。


原始标题:Difference Between Always and OnFailure Kubernetes Restart Policy