节点关闭

在 Kubernetes 集群中,节点 可以通过计划内的优雅方式关闭,也可以因为断电或其他外部原因意外关闭。如果节点在关闭之前没有被清空,节点关闭可能会导致工作负载失败。节点关闭可以是**优雅的**,也可以是**非优雅的**。

优雅的节点关闭

功能状态: Kubernetes v1.21 [测试版]

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=30sshutdownGracePeriodCriticalPods=10s,kubelet 将把节点关闭延迟 30 秒。在关闭期间,前 20 (30-10) 秒将保留用于优雅地终止常规 Pod,最后 10 秒将保留用于终止 关键 Pod

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

功能状态: Kubernetes v1.24 [测试版]

为了在优雅的节点关闭期间围绕 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 归为同一类别进行关闭。

如果特定范围内没有 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 将永远停留在关闭节点上的终止状态。

为了缓解上述情况,用户可以手动将带有 NoExecuteNoSchedule 效果的污点 node.kubernetes.io/out-of-service 添加到节点,将其标记为停止服务。如果在 kube-controller-manager 上启用了 NodeOutOfServiceVolumeDetach功能门控,并且使用此污点将节点标记为停止服务,则如果节点上没有匹配的容忍度,则将强制删除该节点上的 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 必须通过上述非正常节点关闭过程进行恢复。

下一步

详细了解以下内容

上次修改时间:2024 年 4 月 24 日上午 12:43(太平洋标准时间):将节点关闭部分移至集群管理 (f32bcaf081)