节点关机

在 Kubernetes 集群中,节点可以通过计划性的优雅方式关停,也可能由于电源故障或其他外部原因而意外关停。如果在关停前未排空节点,节点关停可能导致工作负载故障。节点关停可以是优雅的非优雅的

优雅的节点关停

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

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

启用优雅节点关停

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

在 Linux 上,优雅节点关停特性由 GracefulNodeShutdown 特性门控控制,该特性在 1.21 版本中默认启用。

特性状态: Kubernetes v1.34 [beta] (默认启用:true)

在 Windows 上,优雅节点关停特性由 WindowsGracefulNodeShutdown 特性门控控制,该特性在 1.32 版本中作为 Alpha 特性引入。在 Kubernetes 1.34 版本中,该特性已升级为 Beta,并默认启用。

Windows 优雅节点关停无法取消。

如果 kubelet 未作为 Windows 服务运行,则无法设置和监控 Preshutdown 事件,节点将不得不通过上述非优雅节点关停程序。

在 Windows 优雅节点关停特性启用,但 kubelet 未作为 Windows 服务运行的情况下,kubelet 将继续运行而不是失败。但是,它会记录一个错误,指示它需要作为 Windows 服务运行。

配置优雅节点关停

请注意,默认情况下,以下两个配置选项 shutdownGracePeriodshutdownGracePeriodCriticalPods 都设置为零,因此不会激活优雅节点关停功能。要激活该特性,两个选项都应适当配置并设置为非零值。

一旦 kubelet 收到节点关停通知,它会为 Node 设置一个 NotReady 状况,其 reason 设置为 "node is shutting down"。kube-scheduler 遵循此状况,不会将任何 Pod 调度到受影响的节点上;其他第三方调度器预计会遵循相同的逻辑。这意味着新的 Pod 将不会被调度到该节点上,因此也不会启动。

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

当 kubelet 通过 API 在其 Node 上设置该状况时,kubelet 也会开始终止所有在本地运行的 Pod。

在优雅关停期间,kubelet 分两个阶段终止 Pod

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

优雅节点关停特性通过两个 KubeletConfiguration 选项进行配置

  • shutdownGracePeriod:

    指定节点应延迟关停的总持续时间。这是常规 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 使用了卷,则 VolumeAttachments 将不会从原始关停节点中删除,因此这些 Pod 使用的卷无法附加到新的运行节点。结果是,在 StatefulSet 上运行的应用程序无法正常运行。如果原始关停节点启动,Pod 将被 kubelet 删除,并在不同的运行节点上创建新的 Pod。如果原始关停节点未启动,这些 Pod 将永远停留在关停节点上的终止状态。

为了缓解上述情况,用户可以手动向节点添加污点 node.kubernetes.io/out-of-service,并带有 NoExecuteNoSchedule 效果,将其标记为停止服务。如果节点被此污点标记为停止服务,则如果 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 必须通过上述非优雅节点关停程序进行恢复。

下一步

了解更多信息:

最后修改时间:2025 年 8 月 19 日下午 12:19 PST:更新优雅节点关停页面以不假设 Linux (47c5fa7808)