正确答案:视情况而定。
想象一下,您有 3 个节点集群,您在其中创建了一个具有 3 个副本和 3-5 个独立 pod 的部署。Pod 被创建并调度到节点。
一切都已启动并正在运行。
假设工作节点node1
有 1 个部署副本和 1 个或多个独立 pod。
节点重启过程的一般顺序如下:
- 节点重新启动,例如。使用
sudo reboot
systemd
重启后,节点按照dependencies指定的顺序启动所有OS进程
- 什么时候
dockerd
启动它什么都不做。此时所有先前的容器都有Exited
状态。
- 启动时
kubelet
,它会向集群请求apiserver
节点属性等于其节点名称的 Pod 列表。
- 从 获得回复后
apiserver
,使用 Docker CRI 为回复中kubelet
描述的所有 pod 启动容器。apiserver
- 当
pause
容器为列表中的每个 Pod 启动时,它会获取由 CNI 二进制文件配置的新 IP 地址,由 Network addon Daemonset 的 Pod 部署。
- 在
kube-proxy
节点上启动 Pod 后,它会更新 iptables 规则以实现 Kubernetes 服务所需的配置,同时考虑到新 Pod 的 IP 地址。
现在事情变得有点复杂了。
根据apiserver
和配置kube-controller-manager
,kubelet
他们对节点没有延迟响应的事实做出反应。
如果节点重新启动足够快,kube-controller-manager
则不会驱逐 Pod,并且它们都保持在同一个节点上调度,RESTARTS
在它们的新容器变为Ready
.
示例 1。
集群是使用 Kubeadm 和 Flannel 网络插件Ubuntu 18.04
在 GCP 中创建的 VM 上创建的。
Kubernetes 版本是v1.18.8
Docker 版本是19.03.12
节点重启后,所有 Pod 的容器都会在新 IP 地址的节点上启动。Pod 会保留它们的名称和位置。
如果 node 长时间停止,node 上的 pods 保持Running
状态,但连接尝试明显超时。
如果节点保持停止状态,大约 5 分钟后,该节点上安排的 Pod 被驱逐kube-controller-manager
并终止。如果我在驱逐之前启动节点,则所有 pod 都保留在节点上。
在驱逐的情况下,独立的 Pod 将永远消失,部署和类似的控制器会创建必要数量的 Pod 来替换被驱逐的 Podkube-scheduler
并将它们放置到适当的节点上。如果新 Pod 不能在另一个节点上调度,例如。由于缺少所需的卷,它将保持在 Pending 状态,直到满足调度要求。
在使用 Ubuntu 18.04 Vagrant box 和 Virtualbox hypervisor 创建的集群上,带有专用于 Kubernetes 网络的仅主机适配器,已停止节点上的 pod 保持在Running
, 但Readiness: false
即使在两小时后仍处于状态,并且从未被驱逐。在 2 小时内启动节点后,所有容器都成功重新启动。
这个配置的行为从 Kubernetesv1.7
一直到最新的v1.19.2
.
示例 2。
集群是在谷歌云 (GKE) 中使用默认kubenet
网络插件创建的:
Kubernetes 版本是1.15.12-gke.20
Node OSContainer-Optimized OS (cos)
重新启动节点后(大约需要 15-20 秒),所有 pod 都会在具有新 IP 地址的节点上启动。Pod 会保留它们的名称和位置。(与示例 1 相同)
如果节点停止,则在短时间内(T1 大约等于 30-60 秒)后,节点上的所有 pod 的状态都会更改为正在终止。几分钟后,它们从 Pod 列表中消失了。由 Deployment 管理的 Pod 会重新调度到具有新名称和 IP 地址的其他节点上。
如果节点池是用 Ubuntu 节点创建的,apiserver 会稍后终止 Pods,T1 大约等于 2-3 分钟。
示例表明,不同集群的worker节点重启后的情况不同,最好在特定集群上进行实验,看看是否能得到预期的结果。
如何配置这些超时: