首页 > 解决方案 > 如果我重新启动一个运行一些 pod 的节点会发生什么

问题描述

假设有一些来自 Deployments/StatefulSet/DaemonSet 等的 pod 在 Kubernetes 节点上运行。

然后我直接重启了节点,然后启动docker,同样参数启动kubelet。

那些豆荚会发生什么?

  1. 它们是否使用从 kubelet 本地保存的元数据重新创建?或者使用从 api-server 检索到的信息?还是从 OCI 运行时恢复并表现得好像什么都没发生?
  2. 是不是只有无状态的pod(no--local-data)才能正常恢复?如果它们中的任何一个具有本地 PV/目录,它们会正常连接回来吗?
  3. 长时间不重启节点怎么办?api-server 会分配其他节点来创建这些 pod 吗?默认超时值是多少?我该如何配置?

我所知道的:

 apiserver
    ^
    |(sync)
    V
  kubelet
    ^
    |(sync)
    V
-------------
| CRI plugin |(like api)
| containerd |(like api-server)
|    runc    |(low-level binary which manages container)
| c' runtime |(container runtime where containers run)
-------------

当 kubelet 从 kube-api-server 收到 PodSpec 时,它像远程服务一样调用 CRI,步骤如下:

  1. 创建 PodSandbox(又名“暂停”图像,始终“停止”)
  2. 创建容器
  3. 运行容器

所以我随着节点和 docker 的重新启动,步骤 1 和 2 已经完成,容器处于“停止”状态;然后当 kubelet 重新启动时,它从 kube-api-server 中提取最新信息,发现容器未处于“运行”状态,因此它调用 CRI 运行容器,然后一切恢复正常。

请帮我确认。

先谢谢啦~

标签: dockerkubernetescontainerskubeletcontainerd

解决方案


好问题。先说几件事;Pod 未固定到某个节点。这些节点主要被视为 Kubernetes 可以用来运行其工作负载的“服务器场”。例如,你给 Kubernetes 一组节点,你也给一组 eg Deployment- 这是应该在你的服务器上运行的应用程序的期望状态。Kubernetes 负责调度这些 Pod,并在集群中的某些内容发生更改时保持它们运行。

独立的 Pod 不受任何管理,因此如果 Pod 崩溃,它不会被恢复。您通常希望将无状态应用程序部署为Deployments,然后启动ReplicaSets管理一组 Pod(例如 4 个 Pod)的应用程序实例。

您想要的状态;a Deploymentwith egreplicas: 4保存在Kubernetes 控制平面内的etcd数据库中。

然后是一组控制器,Deployment负责ReplicaSet保持应用程序的 4 个副本处于活动状态。例如,如果一个节点变得不负责任(或死亡),新的 pod 将在其他节点上创建,如果它们由ReplicaSet.

Kubelet接收调度到节点的PodSpecs,然后通过定期健康检查保持这些 Pod 处于活动状态。

是不是只有无状态的pod(no--local-data)才能正常恢复?

Pod 应该被视为临时的 - 例如可以消失 - 但由管理它们的控制器恢复 - 除非作为独立 Pod 部署。所以不要在 pod 中存储本地数据。

还有StatefulSet一些 Pod,它们用于有状态的工作负载——但分布式的有状态工作负载,通常例如 3 个 Pod,它们使用Raft来复制数据。etcd 数据库是使用 Raft 的分布式数据库示例。


推荐阅读