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

Kubernetes 1.26: 非优雅节点停机进入 Beta

Kubernetes v1.24 引入了对处理非优雅节点关机改进的 Alpha 版实现。在 Kubernetes v1.26 中,此功能升级为 Beta。此功能允许有状态工作负载在原节点关机或处于不可恢复状态(例如硬件故障或操作系统损坏)后,故障转移到其他节点。

什么是 Kubernetes 中的节点关机?

在 Kubernetes 集群中,节点可能会关机。这可能是计划内的,也可能是意外发生的。您可能计划进行安全补丁更新或内核升级并需要重启节点,或者它可能因为虚拟机实例的抢占而关机。节点也可能由于硬件故障或软件问题而关机。

要触发节点关机,您可以在 shell 中运行 shutdownpoweroff 命令,或者物理按下按钮关闭机器电源。

如果在关机前未排空节点,节点关机可能会导致工作负载失败。

接下来,我们将描述什么是优雅节点关机和什么是非优雅节点关机。

什么是优雅节点关机?

kubelet 对优雅节点关机的处理允许 kubelet 检测节点关机事件,在该节点实际关机之前正确地终止其上的 Pod 并释放资源。关键 Pod 在所有普通 Pod 终止后终止,以确保应用程序的基本功能能够尽可能长时间地继续工作。

什么是非优雅节点关机?

只有当 kubelet 的节点关机管理器能够检测到即将发生的节点关机操作时,节点关机才能是优雅的。然而,在某些情况下,kubelet 无法检测到节点关机操作。这可能是因为 shutdown 命令未触发 kubelet 在 Linux 上使用的 Inhibitor Locks 机制,或者是因为用户错误。例如,如果该节点的 shutdownGracePeriodshutdownGracePeriodCriticalPods 详情配置不正确。

当节点关机(或崩溃),且该关机未被 kubelet 节点关机管理器检测到时,就变成了非优雅节点关机。非优雅节点关机对有状态应用来说是个问题。如果一个包含 StatefulSet 部分 Pod 的节点以非优雅方式关机,该 Pod 将无限期地停留在 Terminating 状态,并且控制平面无法在健康节点上为该 StatefulSet 创建替代 Pod。您可以手动删除失败的 Pod,但这对于自愈合集群来说并不理想。类似地,Deployment 创建的、绑定到当前已关机节点的 ReplicaSet Pod 将无限期地停留在 Terminating 状态。如果您设置了水平扩缩限制,即使这些正在终止的 Pod 也会计入限制,因此如果您的工作负载已经达到最大规模,它可能难以自愈合。(顺便说一下:如果发生非优雅关机的节点重新启动,kubelet 会删除旧的 Pod,并且控制平面可以创建一个替代 Pod。)

Beta 版本有哪些新特性?

对于 Kubernetes v1.26,非优雅节点关机功能已升级为 Beta 并默认启用。特性门控 NodeOutOfServiceVolumeDetachkube-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:NoExecutenode.kubernetes.io/out-of-service=nodeshutdown:NoSchedule。如果 Pod 上没有匹配的容忍度 (tolerations),这个污点会触发该节点上的 Pod 被强制删除。连接到关机节点的持久卷将被卸载,新的 Pod 将在另一个运行中的节点上成功创建。

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

注意: 在应用 out-of-service 污点之前,您必须确认节点已处于关机或断电状态(而非重启过程中),无论是用户故意关机还是节点由于硬件故障、操作系统问题等原因宕机。

一旦所有与 out-of-service 节点相关联的工作负载 Pod 都已迁移到新的运行中节点,并且关机节点已经恢复,您应该在该节点恢复后移除该污点。

接下来的计划?

根据反馈和采用情况,Kubernetes 团队计划在 1.27 或 1.28 版本中将非优雅节点关机实现推向全面可用 (GA)。

此功能要求用户手动向节点添加污点以触发工作负载的故障转移,并在节点恢复后移除该污点。

如果有程序化方法可以确定节点确实已关机且节点与存储之间没有 I/O,集群操作员可以通过自动应用 out-of-service 污点来自动化此过程。然后,集群操作员可以在工作负载成功故障转移到另一个运行中节点并且关机节点已恢复后,自动移除该污点。

未来,我们计划寻找方法自动检测并隔离已关机或处于不可恢复状态的节点,并将其工作负载故障转移到另一个节点。

如何了解更多信息?

要了解更多信息,请阅读 Kubernetes 文档中的非优雅节点关机

如何参与?

我们向所有为该功能的设计、实现和审查做出贡献的贡献者表示衷心感谢:

许多人一路以来都帮助审查了设计和实现。我们要感谢所有为此努力做出贡献的人,包括在过去几年中审查了 KEP 和实现的大约 30 人。

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