k8s pod 重启策略RestartPolicy 学习

文章目录

    • [一. 三种重启策略详解](#一. 三种重启策略详解)
      • [1.1. `Always`(默认值)](#1.1. Always(默认值))
      • [1.2. `OnFailure`](#1.2. OnFailure)
      • [1.3. `Never`](#1.3. Never)
    • [二. 重启策略与控制器的关系](#二. 重启策略与控制器的关系)
    • [三. 重启背后的机制:指数退避(Back-off)](#三. 重启背后的机制:指数退避(Back-off))
    • [四. 常见误区澄清](#四. 常见误区澄清)
      • [4.1. `livenessProbe`(存活探针)失败会导致重启吗?](#4.1. livenessProbe(存活探针)失败会导致重启吗?)
      • [4.2. `readinessProbe`(就绪探针)失败会导致重启吗?](#4.2. readinessProbe(就绪探针)失败会导致重启吗?)
      • [4.3. 节点重启后,Pod 会重启吗?](#4.3. 节点重启后,Pod 会重启吗?)
      • [4.4. 如何查看容器的重启次数?](#4.4. 如何查看容器的重启次数?)
    • [五. 最佳实践建议](#五. 最佳实践建议)
      • [5.1. 长期服务用 `Always`](#5.1. 长期服务用 Always)
      • [5.2. 批处理任务用 `OnFailure` + `backoffLimit`](#5.2. 批处理任务用 OnFailure + backoffLimit)
      • [5.3. 避免在 Pod 中处理复杂重启逻辑](#5.3. 避免在 Pod 中处理复杂重启逻辑)
      • [5.4. 调试时使用 `Never`](#5.4. 调试时使用 Never)
      • [5.5. 总结](#5.5. 总结)

在 Kubernetes (K8s) 中, 重启策略(Restart Policy) 是决定当 Pod 中的容器终止(退出)时,Kubelet 应该如何处理该 Pod 的核心机制。与 Docker 不同,K8s 的重启策略是定义在 Pod 级别.spec.restartPolicy),而不是单个容器级别。这意味着 Pod 中的所有容器共享同一个重启策略。


一. 三种重启策略详解

Kubernetes 支持以下三种重启策略:

1.1. Always(默认值)

  • 行为 :无论容器因何种原因退出(正常退出代码 0 或异常退出代码非 0),Kubelet 都会自动重启该容器。
  • 适用控制器Deployment, StatefulSet, DaemonSet, ReplicaSet
  • 场景:长期运行的服务(如 Web 服务器、数据库、API 网关)。只要节点还在,服务就应该一直在线。
  • 注意 :如果手动执行 kubectl delete pod,Pod 会被删除且不会重启(因为控制器会创建一个新的 Pod 来替代它,而不是重启旧的)。

1.2. OnFailure

  • 行为 :只有当容器以非零状态码 (即发生错误/崩溃)退出时,Kubelet 才会重启容器。如果容器正常退出(状态码为 0),则不会重启。
  • 适用控制器Job, CronJob
  • 场景:批处理任务、数据迁移脚本、一次性计算任务。如果任务成功完成(exit 0),就不需要再跑了;如果失败了,则需要重试。

1.3. Never

  • 行为 :无论容器因何种原因退出,Kubelet 永远不会 重启该容器。Pod 的状态将变为 Completed(正常退出)或 Failed(异常退出)。
  • 适用控制器Job(某些特定场景)。
  • 场景:调试任务、只需要运行一次且不在乎结果的任务、或者由外部系统监控并手动重启的任务。

二. 重启策略与控制器的关系

并非所有控制器都支持所有重启策略。K8s 会根据控制器类型强制校验:

控制器类型 支持的 RestartPolicy 说明
Deployment Always 必须始终运行,保证服务可用性。
StatefulSet Always 同上,有状态服务需持续运行。
DaemonSet Always 每个节点上的守护进程需持续运行。
Job OnFailure, Never 任务完成后应结束,失败时可重试。
CronJob OnFailure, Never 同 Job,由定时触发。

❌ 错误示例 :如果你在 Deployment 的 YAML 中设置 restartPolicy: OnFailure,K8s API Server 会直接拒绝创建,报错:Unsupported value: "OnFailure": supported values: "Always"


三. 重启背后的机制:指数退避(Back-off)

为了防止容器因代码 Bug 导致"启动-崩溃-重启"的死循环(CrashLoopBackOff),Kubelet 采用了指数退避算法

  1. 第一次重启:等待 10 秒。
  2. 第二次重启:等待 20 秒。
  3. 第三次重启:等待 40 秒。
  4. ...
  5. 最大等待时间 :上限通常为 5 分钟(300 秒)。

状态变化流程:
Running -> Error/Crash -> CrashLoopBackOff (等待中) -> Running (重试)

你可以在 kubectl describe pod <pod-name> 中看到 Last StateReason: CrashLoopBackOff


四. 常见误区澄清

4.1. livenessProbe(存活探针)失败会导致重启吗?

是的。

如果 livenessProbe 检查失败,Kubelet 会杀死 容器。然后,根据 restartPolicy

  • 如果是 AlwaysOnFailure(且退出码非0),容器会被重启。
  • 如果是 Never,容器死后不再复活。

4.2. readinessProbe(就绪探针)失败会导致重启吗?

不会。
readinessProbe 失败只会将 Pod 从 Service 的 Endpoint 列表中移除(停止流量进入),但不会杀死或重启容器。

4.3. 节点重启后,Pod 会重启吗?

  • 如果 Pod 是由控制器(如 Deployment)管理的,控制器会发现 Pod 缺失,并调度一个新的 Pod 到可用节点上。
  • 这不属于"重启策略"的范畴,而是控制器的**期望状态协调(Reconciliation)**机制。

4.4. 如何查看容器的重启次数?

bash 复制代码
kubectl get pods
# 输出示例:
# NAME                     READY   STATUS    RESTARTS   AGE
# my-app-7d9f6b8c5-x2z9a   1/1     Running   3          10m

RESTARTS 列显示的数字就是该 Pod 历史上被重启的次数。

bash 复制代码
kubectl describe pod <pod-name>
# 在 Containers 部分查看:
# Last State:     Terminated
#   Reason:       Error
#   Exit Code:    1
#   Started:      ...
#   Finished:     ...
# Ready:          True
# Restart Count:  3

五. 最佳实践建议

5.1. 长期服务用 Always

对于 Web 应用、微服务,始终使用 Always。配合 livenessProbe 可以自动恢复死锁或僵死的进程。

5.2. 批处理任务用 OnFailure + backoffLimit

对于 Job,设置 restartPolicy: OnFailure,并在 Job spec 中设置 backoffLimit: 4(默认6次),防止无限重试浪费资源。

5.3. 避免在 Pod 中处理复杂重启逻辑

不要在应用代码里写 while true 来防止退出。让 K8s 管理生命周期,应用应该设计为"无状态"或"可快速启动"。

5.4. 调试时使用 Never

如果容器一启动就崩溃,你可以临时将策略改为 Never,这样容器死后会保留现场,你可以进入容器或通过日志排查问题,而不会被不断重启打断。

5.5. 总结

策略 何时重启 典型用途 控制器支持
Always 任何退出 长期服务 Deployment, StatefulSet, DaemonSet
OnFailure 仅异常退出 批处理/任务 Job, CronJob
Never 从不重启 调试/一次性 Job
相关推荐
曾庆睿1 小时前
【基于 RHEL 9.3 的 K8s + GitLab 全自动化部署环境搭建第一篇】
kubernetes·自动化·gitlab
曾庆睿1 小时前
【基于 RHEL 9.3 的 K8s + GitLab 全自动化部署环境搭建第二篇】
kubernetes·自动化·gitlab
不恋水的雨3 小时前
docker安装clickhouse数据库容器
clickhouse·docker·容器
脑子加油站5 小时前
K8S-RBAC认证中心
云原生·容器·kubernetes·rbac认证
Cat_Rocky5 小时前
K8s RBAC认证 简单讲
java·docker·kubernetes
wufeng无峰5 小时前
docker国内镜像源
运维·docker·容器·镜像
OpenCSG5 小时前
CSGClaw v0.3.0版本更新
运维·docker·容器
东北甜妹5 小时前
K8s RBAC 和持久化存储
云原生·容器·kubernetes
IT菜鸟程5 小时前
2026 年 Docker 镜像加速终极方案:告别拉取卡顿,一键提速
运维·docker·容器