本文发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.24:引入非优雅节点关闭 Alpha 功能

Kubernetes v1.24 引入了对非正常节点关闭的 alpha 支持。此功能允许有状态的工作负载在原始节点关闭或处于不可恢复状态(例如硬件故障或操作系统损坏)后故障转移到不同的节点。

这与正常节点关闭有何不同

您可能听说过 Kubernetes 的正常节点关闭功能,并且想知道非正常节点关闭功能与之有何不同。正常节点关闭允许 Kubernetes 检测节点何时正在干净地关闭,并妥善处理这种情况。只有在 kubelet 可以在实际关闭之前检测到节点关闭操作时,节点关闭才可以是“正常”的。但是,在某些情况下,kubelet 可能无法检测到节点关闭操作。发生这种情况的原因可能是关闭命令未触发 kubelet 所依赖的 systemd 抑制锁机制,或者是因为配置错误(未正确配置 ShutdownGracePeriodShutdownGracePeriodCriticalPods)。

正常节点关闭依赖于特定于 Linux 的支持。kubelet 不会监视 Windows 节点上即将发生的关闭(这可能会在未来的 Kubernetes 版本中更改)。

当节点关闭但 kubelet 未检测到时,该节点上的 Pod 也会非正常关闭。对于无状态应用程序,这通常不是问题(一旦集群检测到受影响的节点或 Pod 失败,ReplicaSet 会添加一个新的 Pod)。对于有状态应用程序,情况更为复杂。如果您使用 StatefulSet 并且该 StatefulSet 中的 Pod 位于非正常失败的节点上,则受影响的 Pod 将被标记为正在终止;StatefulSet 无法创建替换 Pod,因为该 Pod 仍然存在于集群中。因此,在 StatefulSet 上运行的应用程序可能会降级甚至脱机。如果原始的已关闭节点再次启动,则该原始节点上的 kubelet 会报告,删除现有的 Pod,并且控制平面会在另一个正在运行的节点上为该 StatefulSet 创建一个替换 Pod。如果原始节点发生故障并且未启动,则这些有状态的 Pod 将无限期地卡在故障节点上的终止状态。

$ kubectl get pod -o wide
NAME    READY   STATUS        RESTARTS   AGE   IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running       0          100m   10.244.2.4   k8s-node-876-1639279816   <none>           <none>
web-1   1/1     Terminating   0          100m   10.244.1.3   k8s-node-433-1639279804   <none>           <none>

试用新的非正常关闭处理

要使用非正常节点关闭处理,您必须为 kube-controller-manager 组件启用 NodeOutOfServiceVolumeDetach 功能门

在节点关闭的情况下,您可以手动将该节点标记为停止服务。在添加该污点之前,您应确保该节点确实已关闭(而不是正在重新启动)。您可以在 kubelet 未检测到并提前处理的关闭之后添加该污点;可以使用该污点的另一种情况是节点由于硬件故障或操作系统损坏而处于不可恢复的状态。您可以为该污点设置的值可以是 node.kubernetes.io/out-of-service=nodeshutdown: "NoExecute"node.kubernetes.io/out-of-service=nodeshutdown:" NoSchedule"。前提是您已启用前面提到的功能门,在节点上设置停止服务污点意味着,除非 Pod 上有匹配的容忍度,否则该节点上的 Pod 将被删除。连接到关闭节点的持久卷将被分离,并且对于 StatefulSet,将在不同的正在运行的节点上成功创建替换 Pod。

$ kubectl taint nodes <node-name> node.kubernetes.io/out-of-service=nodeshutdown:NoExecute

$ kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE    IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          150m   10.244.2.4   k8s-node-876-1639279816   <none>           <none>
web-1   1/1     Running   0          10m    10.244.1.7   k8s-node-433-1639279804   <none>           <none>

注意:在应用停止服务污点之前,您必须验证节点是否已处于关闭或断电状态(而不是正在重新启动),无论是由于用户有意将其关闭,还是由于硬件故障、操作系统问题等导致节点关闭。

一旦所有链接到停止服务节点的工作负载 Pod 都已移动到新的正在运行的节点,并且已恢复关闭的节点,则应在恢复节点后删除受影响节点上的该污点。如果您知道该节点不会恢复服务,则可以改为从集群中删除该节点。

下一步是什么?

根据反馈和采用情况,Kubernetes 团队计划在 1.25 或 1.26 中将非正常节点关闭实现推向 Beta 版。

此功能要求用户手动将污点添加到节点以触发工作负载故障转移,并在恢复节点后删除污点。将来,我们计划找到自动检测和隔离关闭/失败的节点,并将工作负载自动故障转移到另一个节点的方法。

如何了解更多?

查看有关非正常节点关闭的文档

如何参与?

这个功能的故事很长。Yassine Tijani (yastij) 在两年多前启动了 KEP。Xing Yang (xing-yang) 继续推动这项工作。SIG Storage、SIG Node 和 API 审阅者之间进行了许多讨论,以确定设计细节。Ashutosh Kumar (sonasingh46) 完成了大部分实施工作,并在 Kubernetes 1.24 中将其引入 Alpha 版。

我们要感谢以下人员的深刻见解:Tim Hockin (thockin) 在设计方面的指导,Jing Xu (jingxu97)、Hemant Kumar (gnufied) 和 Michelle Au (msau42) 来自 SIG Storage 方面的审阅,以及 Mrunal Patel (mrunalp)、David Porter (bobbypage)、Derek Carr (derekwaynecarr) 和 Danielle Endocrimes (endocrimes) 来自 SIG Node 方面的审阅。

在此过程中,有许多人帮助审查了设计和实现。我们要感谢所有为这项工作做出贡献的人,包括在过去几年中审查了KEP和实现的约 30 人。

此功能是 SIG Storage 和 SIG Node 之间的合作。对于那些有兴趣参与 Kubernetes 存储系统任何部分的设计和开发的人员,请加入Kubernetes 存储特殊兴趣小组 (SIG)。对于那些有兴趣参与设计和开发支持 Pod 和主机资源之间受控交互的组件的人员,请加入Kubernetes 节点 SIG