本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
平滑节点关闭功能进入 Beta 阶段
优雅的节点关机在 1.21 版本中进入 beta 阶段,它使 kubelet 能够在节点关机期间优雅地驱逐 Pod。
Kubernetes 是一个分布式系统,因此我们需要为不可避免的故障做好准备——节点会发生故障,容器可能会崩溃或重启,而您的工作负载理论上应该能够承受这些灾难性事件。
其中一类常见问题是节点关机或重启时工作负载失败。在节点关机之前,最佳实践是安全地排空并隔离您的节点。这将确保在此节点上运行的所有 Pod 都可以安全地被驱逐。驱逐将确保您的 Pod 能够遵循预期的Pod 终止生命周期,这意味着您的容器将收到 SIGTERM 和/或运行 `preStopHooks`。
在 Kubernetes 1.20 之前(优雅的节点关机作为 Alpha 功能引入),安全的节点排空并不容易:它要求用户事先手动操作排空节点。如果有人或某个系统在未排空节点的情况下将其关闭,您的 Pod 很可能无法安全地从节点中驱逐并突然关闭。与这些 Pod 通信的其他服务可能会因为 Pod 突然退出而出现错误。这种情况的一些示例可能是由于安全补丁导致的重启或短寿命云计算实例的抢占。
Kubernetes 1.21 将优雅的节点关机带入 Beta 阶段。优雅的节点关机让您可以更好地控制一些意外的关机情况。通过优雅的节点关机,kubelet 能够感知底层系统关机事件,并将这些事件传播给 Pod,确保容器尽可能优雅地关闭。这使容器有机会检查其状态或释放它们正在持有的任何资源。
请注意,为了获得最佳可用性,即使启用了优雅的节点关机,您仍应将部署设计为能够抵御节点故障。
它是如何工作的?
在 Linux 上,您的系统可能在许多不同情况下关机。例如:
- 用户或脚本运行 `shutdown -h now` 或 `systemctl poweroff` 或 `systemctl reboot`。
- 物理按下机器上的电源按钮。
- 在云提供商上停止 VM 实例,例如 GCP 上的 `gcloud compute instances stop`。
- 您的云提供商可能会意外终止的抢占式 VM 或 Spot 实例,但会提供简短警告。
这些情况中的许多都是意外的,并且无法保证集群管理员在这些事件发生之前排空了节点。借助优雅的节点关机功能,kubelet 使用一种名为 “抑制锁(Inhibitor Locks)” 的 systemd 机制,以允许在大多数情况下进行排空。使用抑制锁,kubelet 指示 systemd 将系统关机延迟指定的时间,从而为节点排空并驱逐系统上的 Pod 提供机会。
Kubelet 利用此机制确保您的 Pod 将被干净地终止。当 kubelet 启动时,它会获取一个 systemd 延迟类型抑制锁。当系统即将关机时,kubelet 可以利用它之前获取的延迟类型抑制锁,将关机延迟可配置的短时间。这为您的 Pod 提供了额外的终止时间。因此,即使在意外关机期间,您的应用程序也会收到 SIGTERM,preStop 钩子将执行,并且 kubelet 将正确更新 `Ready` 节点条件和相应的 Pod 状态到 api-server。
例如,在启用了优雅节点关机的节点上,您可以看到 kubelet 正在使用抑制锁
kubelet-node ~ # systemd-inhibit --list
Who: kubelet (UID 0/root, PID 1515/kubelet)
What: shutdown
Why: Kubelet needs time to handle node shutdown
Mode: delay
1 inhibitors listed.
我们在设计此功能时考虑的一个重要因素是并非所有 Pod 都相同。例如,节点上运行的一些 Pod,例如与日志相关的 DaemonSet,应该尽可能长时间地运行,以便在关机期间捕获重要的日志。因此,Pod 被分为两类:“常规”和“关键”。关键 Pod 是那些 `priorityClassName` 设置为 `system-cluster-critical` 或 `system-node-critical` 的 Pod;所有其他 Pod 都被视为常规 Pod。
在我们的示例中,日志 DaemonSet 将作为关键 Pod 运行。在优雅的节点关机期间,常规 Pod 首先终止,然后是关键 Pod。例如,这将允许与日志 DaemonSet 相关联的关键 Pod 在常规 Pod 终止期间继续运行并收集日志。
我们将在 Beta 阶段评估是否需要为不同的 Pod 优先级类提供更大的灵活性,并根据需要添加支持,如果您有任何设想的场景,请告诉我们。
我该如何使用它?
优雅的节点关机由 `GracefulNodeShutdown` 功能门控控制,并在 Kubernetes 1.21 中默认启用。
您可以使用两个 kubelet 配置选项配置优雅的节点关机行为:`ShutdownGracePeriod` 和 `ShutdownGracePeriodCriticalPods`。要配置这些选项,您需要编辑通过 `--config` 标志传递给 kubelet 的 kubelet 配置文件;有关更多详细信息,请参阅通过配置文件设置 kubelet 参数。
在关机期间,kubelet 分两个阶段终止 Pod。您可以配置每个阶段的持续时间。
- 终止节点上运行的常规 Pod。
- 终止节点上运行的关键 Pod。
控制关机持续时间的设置为:
ShutdownGracePeriod
- 指定节点应延迟关机的总持续时间。这是常规 Pod 和关键 Pod 终止的总优雅终止期限。
ShutdownGracePeriodCriticalPods
- 指定在节点关机期间终止关键 Pod 的持续时间。这应该小于 `ShutdownGracePeriod`。
例如,如果 `ShutdownGracePeriod=30s` 且 `ShutdownGracePeriodCriticalPods=10s`,则 kubelet 将节点关机延迟 30 秒。在此期间,前 20 秒(30-10)将用于优雅地终止普通 Pod,最后 10 秒将用于终止关键 Pod。
请注意,默认情况下,上述两个配置选项 `ShutdownGracePeriod` 和 `ShutdownGracePeriodCriticalPods` 都设置为零,因此您需要根据您的环境进行适当配置以激活优雅的节点关机功能。
我如何了解更多信息?
我如何参与?
我们始终欢迎您的反馈!SIG Node 定期开会,可以通过 Slack(频道 ` #sig-node `)或 SIG 的邮件列表联系我们