Pod 生命周期
本页描述了 Pod 的生命周期。Pod 遵循定义的生命周期,开始于 Pending
阶段,如果至少有一个主容器启动成功,则进入 Running
阶段,然后根据 Pod 中是否有任何容器终止失败,进入 Succeeded
或 Failed
阶段。
与单个应用程序容器类似,Pod 被认为是相对短暂的(而不是持久的)实体。Pod 被创建、分配唯一 ID (UID),并被调度到节点上运行,直到终止(根据重启策略)或删除。如果 节点 死机,则在该节点上运行(或计划在该节点上运行)的 Pod 将被标记为删除。控制平面会在超时后标记 Pod 以进行删除。
Pod 生命周期
在 Pod 运行期间,kubelet 能够重启容器以处理某些类型的故障。在 Pod 中,Kubernetes 会跟踪不同的容器状态并确定要采取哪些操作以使 Pod 再次健康。
在 Kubernetes API 中,Pod 既有规约,也有实际状态。Pod 对象的状态由一组 Pod 条件组成。如果对你的应用程序有用,你还可以将自定义就绪信息注入到 Pod 的条件数据中。
Pod 在其生命周期中只被调度一次;将 Pod 分配给特定的节点称为**绑定**,选择使用哪个节点的过程称为**调度**。一旦 Pod 被调度并绑定到节点,Kubernetes 就会尝试在该节点上运行该 Pod。Pod 会在该节点上运行,直到它停止或直到 Pod 被终止;如果 Kubernetes 无法在选定的节点上启动 Pod(例如,如果节点在 Pod 启动前崩溃),那么该特定的 Pod 永远不会启动。
你可以使用Pod 调度就绪来延迟 Pod 的调度,直到所有**调度门控**都被移除。例如,你可能想要定义一组 Pod,但只有在所有 Pod 都被创建后才触发调度。
Pod 和故障恢复
如果 Pod 中的某个容器失败,那么 Kubernetes 可能会尝试重启该特定的容器。阅读 Pod 如何处理容器问题以了解更多信息。
然而,Pod 可能会以集群无法从中恢复的方式失败,在这种情况下,Kubernetes 不会尝试进一步修复 Pod;相反,Kubernetes 会删除 Pod,并依赖其他组件来提供自动修复。
如果将 Pod 调度到某个节点,而该节点随后发生故障,则该 Pod 会被视为不健康,Kubernetes 最终会删除该 Pod。Pod 不会在由于缺少资源或节点维护而导致的驱逐中幸存下来。
Kubernetes 使用一个更高层次的抽象,称为控制器,它负责管理相对可支配的 Pod 实例的工作。
给定的 Pod(由 UID 定义)永远不会被“重新调度”到不同的节点;相反,该 Pod 可以被一个新的、几乎相同的 Pod 替换。如果你创建了一个替换 Pod,它甚至可以与旧 Pod 具有相同的名称(如 .metadata.name
),但替换 Pod 将具有与旧 Pod 不同的 .metadata.uid
。
Kubernetes 不保证现有 Pod 的替代品将被调度到与被替换的旧 Pod 相同的节点上。
关联生命周期
当说某些东西具有与 Pod 相同的生命周期时,例如卷,这意味着只要该特定的 Pod(具有该确切的 UID)存在,该东西就存在。如果该 Pod 由于任何原因被删除,即使创建了相同的替代品,相关的东西(在本示例中为卷)也会被销毁并重新创建。
Pod 阶段
Pod 的 status
字段是一个 PodStatus 对象,它具有 phase
字段。
Pod 的阶段是对 Pod 在其生命周期中所处位置的简单、高级概述。该阶段并非旨在成为容器或 Pod 状态的全面汇总,也并非旨在成为全面的状态机。
Pod 阶段值的数量和含义受到严格保护。除了此处记录的内容外,不应假设具有给定 phase
值的 Pod。
以下是 phase
的可能值
值 | 描述 |
---|---|
Pending | Pod 已被 Kubernetes 集群接受,但一个或多个容器尚未设置好并准备好运行。这包括 Pod 等待被调度的时间以及通过网络下载容器镜像所花费的时间。 |
Running | Pod 已绑定到节点,并且所有容器都已创建。至少有一个容器仍在运行,或者正在启动或重启过程中。 |
Succeeded | Pod 中的所有容器都已成功终止,并且不会被重启。 |
Failed | Pod 中的所有容器都已终止,并且至少有一个容器终止失败。也就是说,容器要么以非零状态退出,要么被系统终止,并且未设置为自动重启。 |
Unknown | 由于某种原因,无法获取 Pod 的状态。此阶段通常是由于与 Pod 应该运行的节点通信时发生错误而导致的。 |
注意
当 pod 反复启动失败时,CrashLoopBackOff
可能会出现在某些 kubectl 命令的 Status
字段中。同样,当 pod 被删除时,Terminating
可能会出现在某些 kubectl 命令的 Status
字段中。
请务必不要混淆 _Status_(kubectl 为用户直觉而显示的字段)与 pod 的 phase
。Pod 阶段是 Kubernetes 数据模型和Pod API 的显式部分。
NAMESPACE NAME READY STATUS RESTARTS AGE
alessandras-namespace alessandras-pod 0/1 CrashLoopBackOff 200 2d9h
Pod 有一个优雅终止的期限,默认是 30 秒。你可以使用 --force
标志来强制终止 Pod。
从 Kubernetes 1.27 版本开始,kubelet 会将已删除的 Pod(除了静态 Pod 和没有 finalizer 的强制删除的 Pod)转换为终端状态(Failed
或 Succeeded
,取决于 Pod 容器的退出状态),然后再从 API 服务器中删除它们。
如果一个节点失效或与集群的其余部分断开连接,Kubernetes 会应用策略,将丢失节点上所有 Pod 的 phase
设置为 Failed。
容器状态
除了 Pod 的整体 阶段之外,Kubernetes 还会跟踪 Pod 内每个容器的状态。你可以使用容器生命周期钩子来触发在容器生命周期中的特定点运行的事件。
一旦调度器将 Pod 分配给节点后,kubelet 将使用容器运行时开始为该 Pod 创建容器。容器有三种可能的状态:Waiting
、Running
和 Terminated
。
要检查 Pod 容器的状态,可以使用 kubectl describe pod <pod-name>
。输出将显示该 Pod 中每个容器的状态。
每个状态都有其特定的含义
等待中(Waiting)
如果容器既不处于 Running
状态,也不处于 Terminated
状态,则它处于 Waiting
状态。处于 Waiting
状态的容器仍在运行完成启动所需的操作:例如,从容器镜像仓库拉取容器镜像,或应用 Secret 数据。当你使用 kubectl
查询处于 Waiting
状态的容器的 Pod 时,你还会看到一个 Reason 字段,用于总结容器处于该状态的原因。
Running
Running
状态表示容器正在正常执行,没有问题。如果配置了 postStart
钩子,则该钩子已经执行完毕。当你使用 kubectl
查询处于 Running
状态的容器的 Pod 时,你还会看到有关容器进入 Running
状态的时间的信息。
已终止(Terminated)
处于 Terminated
状态的容器已开始执行,然后要么运行至完成,要么因某种原因失败。当你使用 kubectl
查询处于 Terminated
状态的容器的 Pod 时,你会看到该容器执行周期的原因、退出代码以及开始和结束时间。
如果容器配置了 preStop
钩子,则此钩子将在容器进入 Terminated
状态之前运行。
Pod 如何处理容器问题
Kubernetes 使用 Pod 的 spec
中定义的 restartPolicy
来管理 Pod 内的容器故障。此策略确定 Kubernetes 如何对因错误或其他原因退出的容器做出反应,其遵循以下顺序:
- 初始崩溃:Kubernetes 根据 Pod 的
restartPolicy
尝试立即重启。 - 重复崩溃:在初始崩溃后,Kubernetes 对后续重启应用指数退避延迟,如
restartPolicy
中所述。这可以防止快速、重复的重启尝试使系统过载。 - CrashLoopBackOff 状态:这表明退避延迟机制当前对处于崩溃循环(反复失败并重启)的给定容器生效。
- 退避重置:如果容器成功运行一段时间(例如,10 分钟),Kubernetes 将重置退避延迟,并将任何新的崩溃视为第一次。
实际上,当 Pod 中的容器未能正确启动,然后在一个循环中不断尝试并失败时,CrashLoopBackOff
是一种可能在描述或列出 Pod 时从 kubectl
命令的输出中看到的条件或事件。
换句话说,当容器进入崩溃循环时,Kubernetes 会应用容器重启策略中提到的指数退避延迟。此机制可防止有故障的容器通过连续的失败启动尝试使系统过载。
CrashLoopBackOff
可能由以下问题引起:
- 导致容器退出的应用程序错误。
- 配置错误,例如不正确的环境变量或缺少配置文件。
- 资源限制,其中容器可能没有足够的内存或 CPU 来正常启动。
- 如果应用程序未在预期时间内开始服务,则运行状况检查失败。
- 容器存活探针或启动探针返回
Failure
结果,如探针部分中所述。
要调查 CrashLoopBackOff
问题的根本原因,用户可以:
- 检查日志:使用
kubectl logs <pod-name>
检查容器的日志。这通常是诊断导致崩溃的问题的最直接方法。 - 检查事件:使用
kubectl describe pod <pod-name>
查看 Pod 的事件,其中可以提供有关配置或资源问题的提示。 - 检查配置:确保 Pod 配置(包括环境变量和挂载的卷)正确,并且所有必需的外部资源都可用。
- 检查资源限制:确保为容器分配了足够的 CPU 和内存。有时,增加 Pod 定义中的资源可以解决该问题。
- 调试应用程序:应用程序代码中可能存在错误或配置错误。在本地或开发环境中运行此容器镜像可以帮助诊断特定于应用程序的问题。
容器重启策略
Pod 的 spec
有一个 restartPolicy
字段,其可能的值为 Always、OnFailure 和 Never。默认值为 Always。
Pod 的 restartPolicy
适用于 Pod 中的应用程序容器和常规初始化容器。边车容器会忽略 Pod 级别的 restartPolicy
字段:在 Kubernetes 中,边车被定义为 initContainers
内的条目,其容器级别的 restartPolicy
设置为 Always
。对于因错误而退出的初始化容器,如果 Pod 级别的 restartPolicy
为 OnFailure
或 Always
,则 kubelet 会重启该初始化容器。
Always
:在任何终止后自动重启容器。OnFailure
:仅当容器因错误退出(非零退出状态)时才重启容器。Never
:不自动重启已终止的容器。
当 kubelet 根据配置的重启策略处理容器重启时,这仅适用于在同一 Pod 内并在同一节点上运行的替换容器的重启。Pod 中的容器退出后,kubelet 会使用指数退避延迟(10 秒、20 秒、40 秒,...)重启它们,上限为 300 秒(5 分钟)。一旦容器在没有任何问题的情况下执行了 10 分钟,kubelet 将重置该容器的重启退避计时器。边车容器和 Pod 生命周期解释了在指定初始化容器上的 restartpolicy
字段时的行为。
可配置的容器重启延迟
Kubernetes v1.32 [alpha]
(默认禁用:false)启用 alpha 功能门 KubeletCrashLoopBackOffMax
后,你可以重新配置容器启动重试之间的最大延迟,从默认的 300 秒(5 分钟)开始。此配置是使用 kubelet 配置为每个节点设置的。在你的kubelet 配置中,在 crashLoopBackOff
下,将 maxContainerRestartPeriod
字段设置为 "1s"
和 "300s"
之间。如上文容器重启策略中所述,该节点上的延迟仍将从 10 秒开始,并且每次重启按 2 倍指数增加,但现在将上限设置为你配置的最大值。如果你配置的 maxContainerRestartPeriod
小于默认的初始值 10 秒,则初始延迟将改为设置为配置的最大值。
请参见以下 kubelet 配置示例:
# container restart delays will start at 10s, increasing
# 2x each time they are restarted, to a maximum of 100s
kind: KubeletConfiguration
crashLoopBackOff:
maxContainerRestartPeriod: "100s"
# delays between container restarts will always be 2s
kind: KubeletConfiguration
crashLoopBackOff:
maxContainerRestartPeriod: "2s"
Pod 条件
Pod 有一个 PodStatus,其中包含一个 PodConditions 数组,Pod 已通过或未通过这些条件。Kubelet 管理以下 PodConditions:
PodScheduled
:Pod 已调度到节点。PodReadyToStartContainers
:(beta 功能;默认启用)Pod 沙箱已成功创建并配置了网络。ContainersReady
:Pod 中的所有容器都已就绪。Initialized
:所有初始化容器已成功完成。Ready
:Pod 可以为请求提供服务,并且应添加到所有匹配服务的负载平衡池中。
字段名称 | 描述 |
---|---|
类型 | 此 Pod 条件的名称。 |
状态 | 指示该条件是否适用,可能的值为 "True "、"False " 或 "Unknown "。 |
lastProbeTime | 上次探测 Pod 条件的时间戳。 |
lastTransitionTime | Pod 上次从一种状态转换到另一种状态的时间戳。 |
原因 | 机器可读的 UpperCamelCase 文本,指示条件上次转换的原因。 |
消息 | 人类可读的消息,指示有关上次状态转换的详细信息。 |
Pod 就绪
Kubernetes v1.14 [stable]
你的应用程序可以将额外的反馈或信号注入到 PodStatus 中:Pod 就绪。要使用此功能,请在 Pod 的 spec
中设置 readinessGates
,以指定 kubelet 为 Pod 就绪评估的其他条件列表。
就绪门由 Pod 的 status.condition
字段的当前状态确定。如果 Kubernetes 在 Pod 的 status.conditions
字段中找不到这样的条件,则该条件的状态默认为 "False
"。
这是一个示例:
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
- type: Ready # a built in PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
- type: "www.example.com/feature-1" # an extra PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
containerStatuses:
- containerID: docker://abcd...
ready: true
...
你添加的 Pod 条件必须具有满足 Kubernetes 标签键格式的名称。
Pod 就绪的状态
kubectl patch
命令不支持修补对象状态。要设置 Pod 的这些 status.conditions
,应用程序和操作器应使用 PATCH
操作。你可以使用Kubernetes 客户端库编写代码,以设置 Pod 就绪的自定义 Pod 条件。
对于使用自定义条件的 Pod,当以下两个条件都满足时,该 Pod 才被评估为就绪仅当:
- Pod 中的所有容器都已就绪。
readinessGates
中指定的所有条件均为True
。
当 Pod 的容器都已就绪,但至少缺少一个自定义条件或该条件为 False
时,kubelet 会将 Pod 的条件设置为 ContainersReady
。
Pod 网络就绪
Kubernetes v1.29 [beta]
注意
在早期开发阶段,此条件被命名为PodHasNetwork
。Pod 在节点上调度后,需要被 kubelet 准入,并且需要挂载所有必需的存储卷。一旦这些阶段完成,kubelet 将与容器运行时(使用容器运行时接口 (CRI))合作,设置运行时沙箱并为 Pod 配置网络。如果启用了 PodReadyToStartContainersCondition
特性门控(对于 Kubernetes 1.32,默认启用),则 PodReadyToStartContainers
条件将被添加到 Pod 的 status.conditions
字段中。
当 Kubelet 检测到 Pod 没有配置网络的运行时沙箱时,PodReadyToStartContainers
条件将由 Kubelet 设置为 False
。这发生在以下场景中:
- 在 Pod 生命周期早期,当 kubelet 尚未开始使用容器运行时为 Pod 设置沙箱时。
- 在 Pod 生命周期后期,当 Pod 沙箱由于以下原因被销毁时:
- 节点重启,但 Pod 未被驱逐
- 对于使用虚拟机进行隔离的容器运行时,Pod 沙箱虚拟机重启,这需要创建新的沙箱和全新的容器网络配置。
在运行时插件成功完成 Pod 的沙箱创建和网络配置后,kubelet 会将 PodReadyToStartContainers
条件设置为 True
。在 PodReadyToStartContainers
条件设置为 True
后,kubelet 就可以开始拉取容器镜像并创建容器。
对于带有初始化容器的 Pod,kubelet 会在初始化容器成功完成后(在运行时插件成功创建沙箱和网络配置后)将 Initialized
条件设置为 True
。对于没有初始化容器的 Pod,kubelet 会在开始创建沙箱和网络配置之前将 Initialized
条件设置为 True
。
容器探针
探针 是 kubelet 定期在容器上执行的诊断。要执行诊断,kubelet 要么在容器内执行代码,要么发出网络请求。
检查机制
有四种不同的方法可以使用探针检查容器。每个探针都必须精确定义这四种机制之一:
exec
- 在容器内执行指定的命令。如果命令以状态码 0 退出,则认为诊断成功。
grpc
- 使用 gRPC 执行远程过程调用。目标应实现 gRPC 健康检查。如果响应的
status
为SERVING
,则认为诊断成功。 httpGet
- 对 Pod 的 IP 地址的指定端口和路径执行 HTTP
GET
请求。如果响应的状态码大于或等于 200 且小于 400,则认为诊断成功。 tcpSocket
- 对 Pod 的 IP 地址的指定端口执行 TCP 检查。如果端口打开,则认为诊断成功。如果远程系统(容器)在打开连接后立即关闭连接,则此情况也算作健康。
注意
与其他机制不同,exec
探针的实现涉及每次执行时创建/派生多个进程。因此,在具有较高 Pod 密度、较低 initialDelaySeconds
和 periodSeconds
间隔的集群中,使用 exec 机制配置任何探针可能会给节点的 CPU 使用率带来开销。在这种情况下,请考虑使用替代的探针机制以避免开销。探针结果
每个探针都有三个结果之一:
成功
- 容器通过了诊断。
失败
- 容器诊断失败。
Unknown
- 未知
诊断失败(不应采取任何操作,kubelet 将进行进一步检查)。
探针类型
livenessProbe
- 指示容器是否正在运行。如果存活探针失败,kubelet 会杀死容器,并且该容器将受到其重启策略的约束。如果容器未提供存活探针,则默认状态为
Success
。 readinessProbe
- 指示容器是否已准备好响应请求。如果就绪探针失败,则端点控制器会从与 Pod 匹配的所有服务的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认值为
Failure
。如果容器未提供就绪探针,则默认状态为Success
。 startupProbe
- 指示容器内的应用程序是否已启动。如果提供了启动探针,则会禁用所有其他探针,直到启动探针成功为止。如果启动探针失败,则 kubelet 会杀死容器,并且该容器将受到其重启策略的约束。如果容器未提供启动探针,则默认状态为
Success
。
有关如何设置存活、就绪或启动探针的更多信息,请参阅配置存活、就绪和启动探针。
何时应使用存活探针?
如果容器中的进程能够在遇到问题或变得不健康时自行崩溃,则您不一定需要存活探针;kubelet 将根据 Pod 的 restartPolicy
自动执行正确的操作。
如果您希望在探针失败时杀死并重启容器,则指定存活探针,并指定 restartPolicy
为 Always 或 OnFailure。
何时应使用就绪探针?
如果您希望仅在探针成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是规范中存在就绪探针意味着 Pod 将在不接收任何流量的情况下启动,并且仅在探针开始成功后才开始接收流量。
如果您希望容器能够自行停机以进行维护,则可以指定一个就绪探针,该探针检查特定于就绪的端点,该端点与存活探针不同。
如果您的应用程序对后端服务有严格的依赖关系,则可以同时实现存活探针和就绪探针。当应用程序本身健康时,存活探针会通过,但是就绪探针还会检查每个所需的后端服务是否可用。这有助于您避免将流量定向到只能回复错误消息的 Pod。
如果您的容器需要在启动期间处理加载大量数据、配置文件或迁移,则可以使用启动探针。但是,如果您想检测已失败的应用程序和仍在处理其启动数据的应用程序之间的区别,则您可能更喜欢就绪探针。
注意
如果您希望在删除 Pod 时能够耗尽请求,则不一定需要就绪探针;在删除时,无论就绪探针是否存在,Pod 都会自动进入未就绪状态。Pod 将在未就绪状态下等待 Pod 中的容器停止。何时应使用启动探针?
启动探针对于具有需要很长时间才能投入使用的容器的 Pod 非常有用。您可以为探测容器的启动配置单独的配置,而不是设置较长的存活间隔,从而允许的时间比存活间隔允许的时间更长。
如果您的容器通常在超过 initialDelaySeconds + failureThreshold × periodSeconds
的时间内启动,则应指定一个启动探针,该探针检查与存活探针相同的端点。 periodSeconds
的默认值为 10 秒。然后,应将其 failureThreshold
设置得足够高,以允许容器启动,而不会更改存活探针的默认值。这有助于防止死锁。
Pod 的终止
由于 Pod 代表在集群中的节点上运行的进程,因此允许这些进程在不再需要时正常终止非常重要(而不是被 KILL
信号突然停止而没有机会清理)。
设计目标是使您能够请求删除并知道进程何时终止,但也可以确保删除最终完成。当您请求删除 Pod 时,集群会记录并跟踪允许强制杀死 Pod 之前的预期宽限期。在强制关闭跟踪到位后,kubelet 会尝试正常关闭。
通常,使用 Pod 的正常终止,kubelet 会向容器运行时发出请求,以尝试通过首先向每个容器中的主进程发送 TERM(又名 SIGTERM)信号(带有宽限期超时)来停止 Pod 中的容器。停止容器的请求由容器运行时异步处理。无法保证这些请求的处理顺序。许多容器运行时都遵循容器映像中定义的 STOPSIGNAL
值,如果不同,则发送容器映像配置的 STOPSIGNAL 而不是 TERM。一旦宽限期到期,将向任何剩余的进程发送 KILL 信号,然后从API 服务器中删除 Pod。如果在等待进程终止时重新启动 kubelet 或容器运行时的管理服务,则集群会从头开始重试,包括完整的原始宽限期。
Pod 终止流程,以示例说明
您可以使用
kubectl
工具手动删除特定的 Pod,并使用默认的宽限期(30 秒)。API 服务器中的 Pod 会更新为 Pod 被视为“死亡”的时间以及宽限期。如果您使用
kubectl describe
来检查您正在删除的 Pod,则该 Pod 会显示为“正在终止”。在运行 Pod 的节点上:一旦 kubelet 看到 Pod 已被标记为终止(已设置正常关闭持续时间),kubelet 就会开始本地 Pod 关闭过程。如果 Pod 的某个容器定义了
preStop
钩子,且 Pod 规约中的terminationGracePeriodSeconds
未设置为 0,kubelet 会在该容器内运行此钩子。默认的terminationGracePeriodSeconds
设置为 30 秒。如果
preStop
钩子在优雅期结束后仍在运行,kubelet 会请求一个 2 秒的额外一次性优雅期延长。注意
如果preStop
钩子完成所需的时间长于默认的优雅期,则你必须修改terminationGracePeriodSeconds
以满足需求。kubelet 触发容器运行时向每个容器内的 1 号进程发送 TERM 信号。
如果 Pod 定义了任何特殊的顺序边车容器。否则,Pod 中的容器会以任意顺序在不同时间收到 TERM 信号。如果关闭顺序很重要,请考虑使用
preStop
钩子进行同步(或切换为使用边车容器)。
在 kubelet 开始优雅地关闭 Pod 的同时,控制平面会评估是否要将正在关闭的 Pod 从 EndpointSlice(和 Endpoints)对象中移除,这些对象表示具有配置的Service,其中配置了选择算符。ReplicaSet 和其他工作负载资源不再将正在关闭的 Pod 视为有效、正在服务的副本。
缓慢关闭的 Pod 不应继续提供常规流量,而应开始终止并完成打开的连接。某些应用程序除了完成打开的连接外,还需要更优雅的终止,例如,会话耗尽和完成。
表示正在终止的 Pod 的任何端点都不会立即从 EndpointSlices 中删除,并且状态指示终止状态会从 EndpointSlice API(以及旧的 Endpoints API)中公开。终止端点的
ready
状态始终为false
(为了与 1.26 之前的版本向后兼容),因此负载均衡器不会将其用于常规流量。如果需要耗尽正在终止的 Pod 上的流量,则可以检查实际的就绪状态,作为
serving
条件。你可以在教程Pod 和端点终止流程中找到有关如何实现连接耗尽的更多详细信息
强制 Pod 终止
默认情况下,所有删除操作都在 30 秒内优雅地完成。kubectl delete
命令支持 --grace-period=<seconds>
选项,该选项允许你覆盖默认值并指定自己的值。
将优雅期设置为 0
会强制立即从 API 服务器删除 Pod。如果 Pod 仍在节点上运行,则强制删除会触发 kubelet 开始立即清理。
使用 kubectl 时,你必须指定额外的标志 --force
以及 --grace-period=0
才能执行强制删除。
如果需要强制删除属于 StatefulSet 的 Pod,请参阅有关从 StatefulSet 中删除 Pod 的任务文档。
Pod 关闭和边车容器
如果你的 Pod 包含一个或多个边车容器(重启策略为 Always 的初始化容器),kubelet 将延迟向这些边车容器发送 TERM 信号,直到最后一个主容器完全终止。边车容器将按照它们在 Pod 规约中定义的相反顺序终止。这确保了边车容器会继续为 Pod 中的其他容器提供服务,直到它们不再需要。
这意味着主容器的缓慢终止也会延迟边车容器的终止。如果在终止过程完成之前优雅期到期,则 Pod 可能会进入强制终止。在这种情况下,Pod 中所有剩余的容器将同时终止,并具有较短的优雅期。
同样,如果 Pod 具有超出终止优雅期的 preStop
钩子,则可能会发生紧急终止。通常,如果你使用 preStop
钩子来控制终止顺序而没有边车容器,则现在可以删除它们,并允许 kubelet 自动管理边车终止。
Pod 的垃圾收集
对于失败的 Pod,API 对象会保留在集群的 API 中,直到人工或控制器进程显式删除它们。
Pod 垃圾收集器 (PodGC) 是控制平面中的一个控制器,当 Pod 的数量超过配置的阈值时(由 kube-controller-manager 中的 terminated-pod-gc-threshold
确定),它会清理已终止的 Pod(处于 Succeeded
或 Failed
阶段)。这避免了随着时间的推移创建和终止 Pod 而导致的资源泄漏。
此外,PodGC 还会清理满足以下任何条件的 Pod
- 是孤立的 Pod - 绑定到不再存在的节点,
- 是未调度的终止 Pod,
- 是正在终止的 Pod,绑定到被
node.kubernetes.io/out-of-service
污点的未就绪节点。
在清理 Pod 的同时,如果 Pod 处于非终端阶段,PodGC 还会将其标记为失败。此外,PodGC 在清理孤立 Pod 时会添加 Pod 中断条件。有关更多详细信息,请参阅 Pod 中断条件。
下一步
获取将处理程序附加到容器生命周期事件的实践经验。
获取配置存活性、就绪性和启动探测器的实践经验。
了解有关容器生命周期钩子的更多信息。
了解有关边车容器的更多信息。
有关 API 中 Pod 和容器状态的详细信息,请参阅涵盖 Pod 的
status
的 API 参考文档。