节点关闭

在 Kubernetes 集群中,节点可以以计划的优雅方式关闭,或者由于停电或其他外部原因而意外关闭。如果节点在关闭之前没有被排空,则节点关闭可能会导致工作负载失败。节点关闭可以是优雅的非优雅的

优雅的节点关闭

功能状态: Kubernetes v1.21 [beta](默认启用:true)

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

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

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

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

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

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

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

在 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](默认启用:true)

为了在优雅的节点关闭期间提供更大的灵活性来控制 Pod 的排序,优雅的节点关闭会遵守 Pod 的 PriorityClass,前提是您已在集群中启用此功能。该功能允许集群管理员根据优先级类显式定义优雅的节点关闭期间 Pod 的排序。

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

当优雅节点关闭遵守 Pod 优先级时,就可以分多个阶段进行优雅节点关闭,每个阶段关闭特定优先级类的 Pod。可以使用每个阶段的确切阶段和关闭时间来配置 kubelet。

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

Pod 优先级类名称Pod 优先级类值
custom-class-a100000
custom-class-b10000
custom-class-c1000
常规/未设置0

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,则 kubelet 不会等待该优先级范围内的 Pod。相反,kubelet 会立即跳到下一个优先级类值范围。

如果启用此功能但未提供任何配置,则不会采取任何排序操作。

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

graceful_shutdown_start_time_secondsgraceful_shutdown_end_time_seconds 指标会在 kubelet 子系统下发出,以监控节点关闭。

非优雅节点关闭处理

功能状态: Kubernetes v1.28 [stable](默认启用:true)

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

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

为了缓解上述情况,用户可以手动添加带有 NoExecuteNoSchedule 效果的污点 node.kubernetes.io/out-of-service 到节点,将其标记为停止服务。如果节点被标记为停止服务,并且该节点上的 Pod 没有匹配的容忍度,则 Pod 将会被强制删除,并且在该节点上终止的 Pod 的卷分离操作会立即发生。这允许停止服务的节点上的 Pod 在不同的节点上快速恢复。

在非正常关闭期间,Pod 会在两个阶段终止:

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

超时强制分离存储

在任何 Pod 删除操作未在 6 分钟内成功的情况下,如果节点在该时刻不健康,kubernetes 将会强制分离正在卸载的卷。任何仍在节点上运行且使用强制分离卷的工作负载都将违反 CSI 规范,该规范规定 ControllerUnpublishVolume “**必须**在调用并成功执行所有卷上的 NodeUnstageVolumeNodeUnpublishVolume 之后调用”。在这种情况下,相关节点上的卷可能会遇到数据损坏。

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

可以通过在 kube-controller-manager 中设置 disable-force-detach-on-timeout 配置字段来禁用超时强制分离功能。禁用超时强制分离功能意味着,如果一个卷托管在不健康的节点上超过 6 分钟,则该卷相关的 VolumeAttachment 不会被删除。

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

Windows 正常节点关闭

功能状态: Kubernetes v1.32 [alpha] (默认禁用: false)

Windows 正常节点关闭功能依赖于作为 Windows 服务运行的 kubelet,然后它将具有注册的服务控制处理程序,以使用给定的持续时间延迟预关闭事件。

Windows 正常节点关闭由 WindowsGracefulNodeShutdown 特性门控控制,该特性门控在 1.32 中作为 alpha 功能引入。

Windows 正常节点关闭无法取消。

如果 Kubelet 没有作为 Windows 服务运行,它将无法设置和监视预关闭事件,节点将必须通过上面提到的非正常节点关闭程序。

如果启用了 Windows 正常节点关闭功能,但 kubelet 没有作为 Windows 服务运行,kubelet 将继续运行而不是失败。但是,它将记录一个错误,表明它需要作为 Windows 服务运行。

下一步

了解更多关于以下内容的信息

上次修改时间:2024 年 11 月 14 日 上午 10:47 PST:添加 windows 正常节点关闭文档 (e4bdcbcf5b)