节点关闭

在 Kubernetes 集群中,一个 节点 可以以计划的优雅方式关闭,也可以由于电源故障或其他外部原因意外关闭。如果节点在关闭之前未被清空,则节点关闭可能会导致工作负载失败。节点关闭可以是 **优雅的** 或 **非优雅的**。

优雅节点关闭

功能状态: Kubernetes v1.21 [beta]

Kubelet 尝试检测节点系统关闭并终止在节点上运行的 Pod。

Kubelet 确保 Pod 在节点关闭期间遵循正常的 Pod 终止过程。在节点关闭期间,Kubelet 不会接受新的 Pod(即使这些 Pod 已绑定到节点)。

优雅节点关闭功能依赖于 systemd,因为它利用了 systemd 抑制锁 来延迟节点关闭给定的持续时间。

优雅节点关闭由 GracefulNodeShutdown 功能开关 控制,该开关在 1.21 中默认启用。

请注意,默认情况下,下面描述的两个配置选项 shutdownGracePeriodshutdownGracePeriodCriticalPods 都设置为零,因此不会激活优雅节点关闭功能。要激活该功能,应适当地配置这两个 Kubelet 配置设置并将其设置为非零值。

一旦 systemd 检测到或通知节点关闭,Kubelet 就会在节点上设置一个 NotReady 条件,并将 reason 设置为 "node is shutting down"。Kube-调度器会尊重此条件,不会将任何 Pod 调度到受影响的节点;其他第三方调度器预计会遵循相同的逻辑。这意味着不会将新 Pod 调度到该节点,因此不会启动任何 Pod。

Kubelet 还会在 PodAdmission 阶段拒绝 Pod,如果检测到正在进行的节点关闭,即使 Pod 具有 容忍度 针对 node.kubernetes.io/not-ready:NoSchedule 也不在那里启动。

与 Kubelet 通过 API 在其节点上设置该条件的同时,Kubelet 还开始终止在本地运行的任何 Pod。

在优雅关闭期间,Kubelet 分两个阶段终止 Pod

  1. 终止在节点上运行的常规 Pod。
  2. 终止在节点上运行的 关键 Pod

优雅节点关闭功能通过两个 KubeletConfiguration 选项配置

  • shutdownGracePeriod:
    • 指定节点应延迟关闭的总持续时间。这是常规 Pod 和 关键 Pod 的 Pod 终止的总宽限期。
  • shutdownGracePeriodCriticalPods:
    • 指定用于在节点关闭期间终止 关键 Pod 的持续时间。此值应小于 shutdownGracePeriod

例如,如果 shutdownGracePeriod=30s,而 shutdownGracePeriodCriticalPods=10s,则 Kubelet 将延迟节点关闭 30 秒。在关闭期间,前 20 秒(30-10)将保留用于优雅地终止常规 Pod,最后 10 秒将保留用于终止 关键 Pod

基于 Pod 优先级的优雅节点关闭

功能状态: Kubernetes v1.24 [beta]

为了在优雅节点关闭期间提供更多灵活性,以便在关闭期间对 Pod 的排序进行调整,优雅节点关闭会尊重 Pod 的 PriorityClass,前提是您在集群中启用了此功能。该功能允许集群管理员根据 优先级类 明确定义优雅节点关闭期间 Pod 的排序。

优雅节点关闭 功能(如上所述)分两个阶段关闭 Pod,非关键 Pod,然后是关键 Pod。如果需要额外的灵活性以更细粒度的方式明确定义关闭期间 Pod 的排序,则可以使用基于 Pod 优先级的优雅节点关闭。

当优雅节点关闭尊重 Pod 优先级时,这使得可以在多个阶段执行优雅节点关闭,每个阶段都关闭特定优先级类的 Pod。Kubelet 可以配置每个阶段的确切阶段和关闭时间。

假设集群中有以下自定义 Pod 优先级类

Pod 优先级类名称Pod 优先级类值
custom-class-a100000
custom-class-b10000
custom-class-c1000
regular/unset0

Kubelet 配置 中,shutdownGracePeriodByPodPriority 的设置可能如下所示

Pod 优先级类值关闭期间
10000010 秒
10000180 秒
1000120 秒
060 秒

相应的 Kubelet 配置 YAML 配置将是

shutdownGracePeriodByPodPriority:
  - priority: 100000
    shutdownGracePeriodSeconds: 10
  - priority: 10000
    shutdownGracePeriodSeconds: 180
  - priority: 1000
    shutdownGracePeriodSeconds: 120
  - priority: 0
    shutdownGracePeriodSeconds: 60

上表意味着任何 priority 值 >= 100000 的 Pod 都只有 10 秒的时间停止,任何值 >= 10000 且 < 100000 的 Pod 都只有 180 秒的时间停止,任何值 >= 1000 且 < 10000 的 Pod 都只有 120 秒的时间停止。最后,所有其他 Pod 将有 60 秒的时间停止。

不必指定与所有类相对应的值。例如,您可以使用以下设置

Pod 优先级类值关闭期间
100000300 秒
1000120 秒
060 秒

在上述情况下,custom-class-b 的 Pod 将与 custom-class-c 的 Pod 进入相同的关闭桶。

如果某个特定范围内没有 Pod,则 Kubelet 不会等待该优先级范围内的 Pod。相反,Kubelet 会立即跳到下一个优先级类值范围。

如果启用了此功能并且没有提供任何配置,则不会执行任何排序操作。

使用此功能需要启用 GracefulNodeShutdownBasedOnPodPriority 功能开关,并将 Kubelet 配置 中的 ShutdownGracePeriodByPodPriority 设置为包含 Pod 优先级类值及其各自关闭期间的所需配置。

指标 graceful_shutdown_start_time_secondsgraceful_shutdown_end_time_seconds 在 Kubelet 子系统下发出,用于监控节点关闭。

非优雅节点关闭处理

功能状态: Kubernetes v1.28 [稳定]

Kubelet 的节点关闭管理器可能无法检测到节点关闭操作,原因可能是命令没有触发 Kubelet 使用的抑制锁机制,或者是因为用户错误,即 ShutdownGracePeriod 和 ShutdownGracePeriodCriticalPods 未正确配置。有关更多详细信息,请参考上面的部分 优雅节点关闭

当节点关闭但未被 Kubelet 的节点关闭管理器检测到时,属于 StatefulSet 的 Pod 将停留在关闭节点上的终止状态,并且无法移动到新的运行节点。这是因为关闭节点上的 Kubelet 无法删除 Pod,因此 StatefulSet 无法创建具有相同名称的新 Pod。如果 Pod 使用了卷,则 VolumeAttachments 不会从原始关闭节点中删除,因此这些 Pod 使用的卷无法附加到新的运行节点。结果,在 StatefulSet 上运行的应用程序无法正常运行。如果原始关闭节点启动,Kubelet 会删除这些 Pod,并在不同的运行节点上创建新的 Pod。如果原始关闭节点未启动,这些 Pod 将永远停留在关闭节点上的终止状态。

为了缓解上述情况,用户可以手动将污点 node.kubernetes.io/out-of-service 添加到节点,并使用 NoExecuteNoSchedule 效果标记其为停用。如果在 kube-controller-manager 上启用了 NodeOutOfServiceVolumeDetach功能开关,并且节点使用此污点标记为停用,如果节点上没有匹配的容忍度,则节点上的 Pod 将被强制删除,并且在节点上终止的 Pod 的卷分离操作将立即发生。这使得停用节点上的 Pod 可以在其他节点上快速恢复。

在非优雅关闭期间,Pod 分两个阶段终止

  1. 强制删除没有匹配 out-of-service 容忍度的 Pod。
  2. 立即对这些 Pod 执行分离卷操作。

超时强制存储分离

在任何情况下,如果 Pod 删除在 6 分钟内未成功,并且节点此时处于不健康状态,Kubernetes 将强制分离正在卸载的卷。任何仍在节点上运行并使用强制分离卷的工作负载都将违反 CSI 规范,该规范指出 `ControllerUnpublishVolume` “**必须**在所有卷上的 `NodeUnstageVolume` 和 `NodeUnpublishVolume` 被调用并成功后调用”。在这种情况下,问题节点上的卷可能会遇到数据损坏。

强制存储分离行为是可选的;用户可以选择使用“非正常节点关闭”功能。

可以通过在 `kube-controller-manager` 中设置 `disable-force-detach-on-timeout` 配置字段来禁用超时强制存储分离。禁用超时强制分离功能意味着托管在超过 6 分钟处于不健康状态的节点上的卷不会与其关联的 VolumeAttachment 被删除。

应用此设置后,仍然附加到卷的不健康 Pod 必须通过上面提到的 非正常节点关闭 过程来恢复。

下一步

了解更多信息

上次修改于 2024 年 4 月 24 日凌晨 12:43 PST:将节点关闭部分移动到集群管理 (f32bcaf081)