本文已发布一年以上。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.26:非优雅节点关闭进入 Beta 阶段
Kubernetes v1.24 引入了针对非优雅节点关闭的改进的 Alpha 质量实现。在 Kubernetes v1.26 中,此特性进入 Beta 阶段。此特性允许有状态工作负载在原始节点关闭或处于不可恢复状态(例如硬件故障或操作系统损坏)后,故障转移到不同的节点。
Kubernetes 中的节点关闭是什么?
在 Kubernetes 集群中,节点可能会关闭。这可能以计划的方式发生,也可能意外发生。你可能计划进行安全补丁或内核升级,需要重启节点,或者由于 VM 实例被抢占而关闭。节点也可能因硬件故障或软件问题而关闭。
要触发节点关闭,你可以在 shell 中运行 shutdown
或 poweroff
命令,或者物理按下按钮来关闭机器电源。
如果在关闭之前没有排空节点,则节点关闭可能会导致工作负载失败。
在下面,我们将描述什么是优雅节点关闭,什么是非优雅节点关闭。
什么是优雅节点关闭?
kubelet 对优雅节点关闭的处理允许 kubelet 检测节点关闭事件,正确终止该节点上的 Pod,并在实际关闭之前释放资源。关键 Pod 在所有常规 Pod 终止后终止,以确保应用程序的基本功能尽可能长时间地继续工作。
什么是非优雅节点关闭?
只有当 kubelet 的 *节点关闭管理器* 可以检测到即将到来的节点关闭操作时,节点关闭才能是优雅的。但是,在某些情况下,kubelet 不会检测到节点关闭操作。这可能是因为 shutdown
命令没有触发 Linux 上 kubelet 使用的 Inhibitor Locks 机制,或者因为用户错误。例如,如果该节点的 shutdownGracePeriod
和 shutdownGracePeriodCriticalPods
详细信息配置不正确。
当节点关闭(或崩溃),并且 kubelet 节点关闭管理器 **未** 检测到该关闭时,它将变为非优雅节点关闭。非优雅节点关闭对于有状态应用程序来说是一个问题。如果包含作为 StatefulSet 一部分的 Pod 的节点以非优雅的方式关闭,则该 Pod 将无限期地卡在 Terminating
状态,并且控制平面无法在该 StatefulSet 的健康节点上创建替换 Pod。你可以手动删除失败的 Pod,但这对于自我修复的集群来说并不理想。类似地,作为 Deployment 一部分创建的 ReplicaSet 的 Pod 将卡在 Terminating
状态,并且绑定到现在已关闭的节点,无限期地保持为 Terminating
。如果你设置了水平缩放限制,即使是那些正在终止的 Pod 也会计入限制,因此如果你的工作负载已经达到最大规模,则可能难以自我修复。(顺便说一句:如果执行了非优雅关闭的节点重新启动,则 kubelet 会删除旧的 Pod,并且控制平面可以进行替换。)
Beta 版本的新功能是什么?
对于 Kubernetes v1.26,非优雅节点关闭功能是 Beta 版,并且默认启用。NodeOutOfServiceVolumeDetach
特性门控在 kube-controller-manager
上默认启用,而不是选择加入;如果需要,你仍然可以禁用它(也请提交一个 issue 来解释问题)。
在检测方面,kube-controller-manager 报告了两个新的指标。
force_delete_pods_total
- 正在被强制删除的 Pod 的数量(在 Pod 垃圾回收控制器重启时重置)
force_delete_pod_errors_total
- 尝试强制删除 Pod 时遇到的错误数量(也在 Pod 垃圾回收控制器重启时重置)
它是如何工作的?
在节点关闭的情况下,如果优雅关闭不起作用或者节点由于硬件故障或操作系统损坏而处于不可恢复状态,你可以手动在节点上添加 out-of-service
污点。例如,这可以是 node.kubernetes.io/out-of-service=nodeshutdown:NoExecute
或 node.kubernetes.io/out-of-service=nodeshutdown:NoSchedule
。如果 Pod 上没有匹配的容忍度,则此污点会触发强制删除节点上的 Pod。附加到已关闭节点的持久卷将被分离,并且将在不同的运行节点上成功创建新的 Pod。
kubectl taint nodes <node-name> node.kubernetes.io/out-of-service=nodeshutdown:NoExecute
注意: 在应用 out-of-service 污点之前,你必须验证节点是否已处于关闭或断电状态(而不是正在重启过程中),要么是因为用户有意将其关闭,要么是因为硬件故障、操作系统问题等导致节点关闭。
一旦所有链接到 out-of-service 节点的 workload Pod 都被移动到新的运行节点,并且已关闭的节点已恢复,你应在该节点恢复后删除受影响节点上的污点。
下一步是什么?
根据反馈和采用情况,Kubernetes 团队计划在 1.27 或 1.28 版本中将非优雅节点关闭的实现推向 GA。
此特性要求用户手动向节点添加污点以触发工作负载的故障转移,并在节点恢复后删除污点。
如果可以通过编程方式确定节点确实已关闭,并且节点和存储之间没有 IO,则集群操作员可以通过自动应用 out-of-service
污点来自动执行此过程。然后,集群操作员可以在工作负载成功故障转移到另一个运行节点并且已关闭的节点已恢复后,自动删除污点。
未来,我们计划找到自动检测和隔离已关闭或处于不可恢复状态的节点,并将其工作负载故障转移到另一个节点的方法。
如何了解更多?
要了解更多信息,请阅读 Kubernetes 文档中的非优雅节点关闭。
如何参与?
我们非常感谢所有为该特性的设计、实施和审查做出贡献的人员
- Michelle Au (msau42)
- Derek Carr (derekwaynecarr)
- Danielle Endocrimes (endocrimes)
- Tim Hockin (thockin)
- Ashutosh Kumar (sonasingh46)
- Hemant Kumar (gnufied)
- Yuiko Mouri(YuikoTakada)
- Mrunal Patel (mrunalp)
- David Porter (bobbypage)
- Yassine Tijani (yastij)
- Jing Xu (jingxu97)
- Xing Yang (xing-yang)
一路上有很多人帮助审查了设计和实施。我们要感谢所有为这项工作做出贡献的人,包括过去几年审查了 KEP 和实施的约 30 人。
此特性是 SIG Storage 和 SIG Node 之间的合作。对于那些有兴趣参与 Kubernetes 存储系统任何部分的设计和开发的,请加入 Kubernetes 存储特别兴趣小组 (SIG)。对于那些有兴趣参与支持 Pod 和主机资源之间受控交互的组件的设计和开发的,请加入 Kubernetes Node SIG。