一个计算机技术爱好者与学习者

0%

好好学K8S:K8S节点关机后会发生什么?

1. 问题描述

当一个k8s节点关机后,k8s会对pod做什么操作?
答:k8s发现节点不可用之后,过一段时间节点还没有恢复,会在其他节点上拉起挂掉节点上的pod。

这个回答对,但是只对了一半。适用于deployment,并不适用于statefulset。

2. 正确解答

参考文档:

k8s节点关闭分为节点体面关闭和节点非体面关闭。

2.1. 节点体面关闭

kubelet 会尝试检测节点系统关闭事件并终止在节点上运行的所有 Pod。

在节点终止期间,kubelet 保证 Pod 遵从常规的 Pod 终止流程。

节点体面关闭特性依赖于 systemd,因为它要利用 systemd 抑制器锁机制, 在给定的期限内延迟节点关闭。

节点体面关闭特性受 GracefulNodeShutdown 特性门控控制, 在 1.21 版本中是默认启用的。

在体面关闭节点过程中,kubelet 分两个阶段来终止 Pod:

  • 终止在节点上运行的常规 Pod。
  • 终止在节点上运行的关键 Pod。

2.2. 节点非体面关闭

节点关闭的操作可能无法被 kubelet 的节点关闭管理器检测到, 是因为该命令不会触发 kubelet 所使用的抑制锁定机制,或者是因为用户错误的原因, 即 ShutdownGracePeriod 和 ShutdownGracePeriodCriticalPod 配置不正确。

当某节点关闭但 kubelet 的节点关闭管理器未检测到这一事件时, 在那个已关闭节点上、属于 StatefulSet 的 Pod 将停滞于终止状态,并且不能移动到新的运行节点上。 这是因为已关闭节点上的 kubelet 已不存在,亦无法删除 Pod, 因此 StatefulSet 无法创建同名的新 Pod。 如果 Pod 使用了卷,则 VolumeAttachments 不会从原来的已关闭节点上删除, 因此这些 Pod 所使用的卷也无法挂接到新的运行节点上。 所以,那些以 StatefulSet 形式运行的应用无法正常工作。 如果原来的已关闭节点被恢复,kubelet 将删除 Pod,新的 Pod 将被在不同的运行节点上创建。 如果原来的已关闭节点没有被恢复,那些在已关闭节点上的 Pod 将永远滞留在终止状态。

为了缓解上述情况,用户可以手动将具有 NoExecute 或 NoSchedule 效果的 node.kubernetes.io/out-of-service 污点添加到节点上,标记其无法提供服务。 如果在 kube-controller-manager 上启用了 NodeOutOfServiceVolumeDetach 特性门控, 并且节点被通过污点标记为无法提供服务,如果节点 Pod 上没有设置对应的容忍度, 那么这样的 Pod 将被强制删除,并且该在节点上被终止的 Pod 将立即进行卷分离操作。 这样就允许那些在无法提供服务节点上的 Pod 能在其他节点上快速恢复。

在非体面关闭期间,Pod 分两个阶段终止:

  • 强制删除没有匹配的 out-of-service 容忍度的 Pod。
  • 立即对此类 Pod 执行分离卷操作。

3. statefulset处理

如果没有配置节点体面关闭,直接关机了一个k8s节点,怎样恢复节点上的statefulset pod?
答:强制删除statefulset pod(从k8s apiserver中删除)。例如:

1
kubectl delete pod mysql-2 -n mysql --force

4. 后记

很多问题并不是想象的那样,不能想当然,还是需要好好读一遍k8s文档。

  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-k8s-node-shutdown/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~