Kubelet 状态更新机制

kubernetes-reliability

当 Kubernetes 中 Node 节点出现状态异常时,节点上的 Pod 会被重新调度到其他节点上,由于和 Kubelet 的状态更新机制有关,当节点宕机后,Pod 并不会立即触发重新调度到其他节点。

  • kubelet 自身会定期更新状态到 kube-apiserver,通过参数 –node-status-update-frequency 指定上报频率,默认为10s 上报一次。
  • kube-controller-manager 通过参数 –node-monitor-period 检查 kubelet 的状态,默认为5s。
  • 当 node 被 kubernetes 判定为 notready 状态,通过 –node-monitor-grace-period 参数配置,默认为40s。
  • 当 node 被 kubernetes 判定为 unhealthy 状态,通过 –node-startup-grace-period 参数配置,默认为1m。
  • kubernetes 开始删除原 node 上的 pod,通过 –pod-eviction-timeout 参数配置,默认为5m。

kube-controller-manager 和 kubelet 都是异步工作的,在这过程中,可能会因为网络延迟、apiserver 的延迟、etcd 延迟、节点负载导致的延迟。所以,如果 –node-status-update-frequency 设置为5s,实际上,etcd 中的数据变化则会在 6~7s。

Kubelet 在更新状态失败时,会进行重试,默认为5次,通过配置参数 nodeStatusUpdateRetry。Kubelet 会在函数 tryUpdateNodeStatus 中尝试进行状态更新。Kubelet 使用了 golang 中的 http.Client()方法,但是没有至指定超时时间,所以,如果 apiserver 过载时,当建立 TCP 连接时可能会出现一些故障。因此,在 nodeStatusUpdateRetry * –node-status-update-frequency 时间后才会更新一次节点状态。同时,Kubernetes 的 controller manager 将尝试每–node-monitor-period 时间周期内检查 nodeStatusUpdateRetry 次。在 –node-monitor-grace-period 之后,会认为节点 unhealthy,然后会在 –pod-eviction-timeout 后删除 pod。kube-proxy 拥有一个 watch API,一旦 pod 被驱逐了,kube-proxy 将会通知更新节点的 iptables 规则,将 pod 从 service 的 endpoints 中移除,保证不会访问到来自故障节点的 pod。

对于这些参数的配置,需要根据不同的集群规模进行选择。

社区默认配置
参数
–node-status-update-frequency 10s
–node-monitor-period 5s
–node-monitor-grace-period 40s
–pod-eviction-timeout 5m
快速更新和快速响应
参数
–node-status-update-frequency 4s
–node-monitor-period 2s
–node-monitor-grace-period 20s
–pod-eviction-timeout 30s

在这种情况下,pod 将在50s 内逐出,因为该节点在20s 后将被视为 down,并且–pod-eviction-timeout 在30s 之后发生。 但是,这种情况会在 etcd 上产生开销,因为每个节点都会尝试每2秒更新一次状态。如果环境有1000个节点,那么每分钟将有15000个节点更新,这可能需要大型etcd容器甚至是etcd的专用节点。

如果我们计算尝试次数,则除法将给出5,但实际上每次尝试的 nodeStatusUpdateRetry 尝试将从3到5。 由于所有组件的延迟,尝试总次数将在15到25之间变化。

中等更新和平均响应
参数
–node-status-update-frequency 20s
–node-monitor-period 5s
–node-monitor-grace-period 2m
–pod-eviction-timeout 1m

在这种情况下,Kubelet 将尝试每20秒更新一次状态。因此,在 controller manager 在节点的不健康状态之前,它将是6 * 5 = 30次尝试。1m后,它将驱逐所 pod。驱逐前的总时间为3m。这种情况适用于中等环境,因为1000个节点每分钟需要3000个etcd更新。

实际上,将有4到6个节点更新尝试。 尝试总次数从20到30不等。

低更新和慢响应
参数
–node-status-update-frequency 1m
–node-monitor-period 5s
–node-monitor-grace-period 5m
–pod-eviction-timeout 1m

在这种情况下,每个 kubelet 都会尝试每分钟更新一次状态。在不健康状态之前将有5 * 5 = 25次尝试。5m后,controller manager 将设置不健康状态。 这意味着 pod 在被标记为不健康后1m后将被驱逐。(总共花费6m)。

实际上,将有3到5次尝试。 尝试总次数从15到25不等。

-------------本文结束感谢您的阅读-------------