此文档中的信息可能已过时
此文档的更新日期比原文晚,因此其中的信息可能已过时。如果能阅读英文,请查看英文版本以获取最新信息: What Happens After A Node Restart
节点上的系统组件有时会重新启动,可能是因为升级、崩溃或管理员的显式操作。本文描述了当 kubelet、 容器运行时 或整个节点重新启动时,Pod 和节点会发生什么。
在健康的集群中,这些重启通常是安全的,不会破坏正在运行的工作负载。以下部分描述需要注意的影响, 这些影响在大型或负载较重的节点上会更加明显。 最具破坏性的情况是节点重启, 它包含容器运行时重启和 kubelet 重启,但后果更严重,因为节点上的每个容器都会首先停止。
如果只有 kubelet 重新启动,已经运行的容器继续运行。 kubelet 重新建立其对节点的视图,并根据期望状态协调正在运行的容器。 在此期间,会发生以下情况:
NotReady。当节点处于 NotReady 状态时,
调度器不会在其上放置新的 Pod。Lease 对象并再次发布节点状态),心跳就会恢复。false 是默认行为。
ChangeContainerStatusOnKubeletRestart
特性门控
允许你恢复到该行为,但这是一个已弃用的遗留后门,计划移除,因此你不应依赖它。
有关详细信息,请参阅
kubelet 重启期间的 Pod 行为。总体而言,在健康的集群中,kubelet 重启不会破坏正在运行的工作负载。然而,在节点过度使用的大型集群中, 重新初始化负载以及暂停的垃圾回收和驱逐可能会导致系统不稳定。
Kubernetes 没有定义容器运行时重启时的行为。 根据你使用的容器运行时,重启可能会触发所有本地容器的停止或重启。 然而,大多数与 Kubernetes 一起使用的容器运行时都使用一种允许你重启运行时而让容器继续执行的配置。
当容器运行时(如 containerd 或 CRI-O) 重新启动时,kubelet 会失去与运行时的连接,直到运行时恢复。在此期间:
exec 探针
会失败,因为 kubelet 无法在容器内运行命令。如果超时时间短且失败阈值低,失败的存活探针会导致容器重启,
失败的就绪探针会导致 Pod 在 Ready 状态之间波动。NotReady,这会阻止在该节点上调度新的 Pod。在极少数情况下,在精确时刻中断操作可能会导致状态不一致:
中断的镜像拉取可能会留下不一致的镜像层,这可能会使镜像无法使用,直到再次拉取。
中断的 Sandbox 创建,如果在 CNI 或 NRI 调用中途终止,可能会使 Sandbox 处于不一致状态, CNI 仅部分初始化,并可能出现资源泄漏。
在精确时刻中断操作是低概率事件,因此重启容器运行时通常是安全的操作。在负载较重的节点上, 每个操作都较慢,中断关键操作的时间窗口更大,遇到这些边缘情况的概率会增加。
节点重启是这些事件中最具破坏性的,因为节点上的每个容器都会停止。重启包含容器运行时重启和 kubelet 重启,但后果更严重:独立的 kubelet 或运行时重启会让已运行的容器保持不变, 而重启会首先停止每个容器。节点启动后,kubelet 和容器运行时重新启动,但没有任何容器实际运行。
在计划重启之前,你可以通过隔离(cordon)节点来减少影响,使调度器停止在其上放置新的 Pod, 然后腾空节点以优雅地驱逐现有 Pod。 当启用体面节点关闭时, kubelet 还会在检测到节点正在关闭时尝试干净地停止运行中的 Pod。
当节点恢复时:
NotReady。
当节点处于 NotReady 状态时,节点可能会被标记污点
node.kubernetes.io/not-ready,在配置的容忍期过后,控制平面可以驱逐不容忍该污点的 Pod。emptyDir 卷的生命周期与 Pod 在节点上的时间相同:
内存支持的 emptyDir(medium: Memory)在重启时总是会丢失,因为它存储在 RAM 中,
而磁盘支持的 emptyDir 只要 Pod 不被驱逐或删除,就能在重启后存活,只有当 Pod 离开节点时才会被删除。对于必须容忍节点重启的工作负载,请通过控制器运行 Pod, 对必须存活的数据使用持久卷, 并配置中断预算和探针, 以便只在 Pod 就绪后才向其发送流量。