在K8S中,Pod 的重启策略有哪些?
好的,这是一个非常关键的概念。在 Kubernetes 中,Pod 的重启策略(Restart Policy)决定了当容器终止或健康检查失败时,kubelet 应该如何应对。
核心概念
Pod 的 restartPolicy
是应用于 Pod 内所有容器 的顶级规格(spec)字段。它定义了当容器进程退出(无论正常还是异常)时,kubelet 是否以及如何重启它们。
三种重启策略
Kubernetes 提供了三种重启策略:
1. Always
(总是重启)
- 行为:这是默认的重启策略。只要 Pod 中的容器终止运行(无论退出代码是什么),kubelet 就会自动重启它。
- 适用场景:适用于需要长期运行的服务类应用(如 Web 服务器、API 后端、数据库等)。这也是
Deployment
、StatefulSet
、ReplicaSet
等控制器管理的 Pod 最常用的策略,以确保维持指定的副本数。
2. OnFailure
(失败时重启)
- 行为:只有当容器以非零状态码终止(即发生错误或异常退出)时,kubelet 才会重启它。如果容器正常退出(退出码为 0),则不会重启。
- 适用场景:适用于批处理任务或一次性任务(Job)。你希望任务在成功完成后就停止,但如果执行过程中发生错误,则自动重试。
3. Never
(从不重启)
- 行为:无论容器因何种原因退出(成功或失败),kubelet 都不会重启它。
- 适用场景:适用于你希望手动控制重启行为的场景,或者用于运行你明确知道不需要重启的特定任务。
工作机制与细节
-
由 kubelet 执行:重启策略由节点上的 kubelet 强制执行,而不是由 Kubernetes API 服务器控制。kubelet 会以指数后退延迟(10秒, 20秒, 40秒, ...最多 5 分钟)的方式重启容器,以防止频繁重启消耗资源。
-
与控制器的关系:
Deployment
/StatefulSet
/ReplicaSet
:这些控制器依赖于Always
策略来维持所需的副本数量。如果它们管理的 Pod 被终止(例如因节点故障),控制器会在其他节点上创建一个全新的 Pod(restartPolicy: Always
),而不是重启原Pod。这里的“重启”是控制器层面的替换,而非 kubelet 对容器的重启。Job
:用于运行一次性任务。它通常使用restartPolicy: OnFailure
或Never
。如果任务失败,Job
控制器会根据backoffLimit
等配置创建新的 Pod 来重试任务。DaemonSet
:确保每个节点上都运行一个 Pod 副本。如果 DaemonSet 的 Pod 被终止,它会在原节点上创建一个新的 Pod 来替代。
-
与探针的交互:
livenessProbe
(存活探针):如果存活探针失败,kubelet 会杀死容器,然后容器的命运就由restartPolicy
决定。如果是Always
或OnFailure
,容器会被重启。readinessProbe
(就绪探针):就绪探针失败不会导致容器重启,只会将其从 Service 的负载均衡中移除。
配置示例
示例 1:用于 Deployment/长期运行服务 (Always
)
apiVersion: v1
kind: Pod
metadata:
name: always-restart-pod
spec:
containers:
- name: nginx
image: nginx
restartPolicy: Always # 默认值,可以省略。保证Nginx服务永远运行。
示例 2:用于批处理任务 Job (OnFailure
或 Never
)
apiVersion: batch/v1
kind: Job
metadata:
name: hello-job
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && exit 1'] # 这里会故意失败
restartPolicy: OnFailure # 任务失败时会重试,如果成功则退出
backoffLimit: 4 # 定义Job的重试次数
示例 3:明确不重启的任务 (Never
)
apiVersion: v1
kind: Pod
metadata:
name: one-time-task-pod
spec:
containers:
- name: task
image: busybox
command: ['sh', '-c', 'date > /tmp/date.log'] # 执行一个命令并退出
restartPolicy: Never # 命令执行完,无论成功与否,都不再重启
总结
重启策略 | 行为 | 典型应用控制器 | 适用场景 |
---|---|---|---|
Always |
容器终止就重启 | Deployment , StatefulSet , ReplicaSet , DaemonSet |
长期运行的服务(Web, API, DB) |
OnFailure |
容器异常退出才重启 | Job |
批处理任务,需要自动重试失败的任务 |
Never |
任何情况都不重启 | Job (某些情况) |
一次性任务,无需重试或需要手动处理失败 |
关键要点:
- 重启策略由
kubelet
在节点级别执行,针对的是容器。 - 控制器(如 Deployment、Job)通过创建或删除Pod来维持预期状态,这与 kubelet 重启容器是两个不同层面的操作。
- 对于大多数微服务和应用,使用默认的
Always
策略即可。 - 对于任务型工作负载,根据是否需要自动重试来选择
OnFailure
或Never
。