Kubelet 状态更新机制
当 Kubernetes 中 Node 节点出现状态异常的情况下,节点上的 Pod 会被重新调度到其他节点上去,但是有的时候我们会发现节点 Down 掉以后,Pod 并不会立即触发重新调度,这实际上就是和 Kubelet 的状态更新机制密切相关的,Kubernetes 提供了一些参数配置来触发重新调度到node时间,下面我们来分析下 Kubelet 状态更新的基本流程。
默认情况下,正常的行为如下:
kubelet
定期向apiserver
发送其状态,发送周期由--node-status-update-frequency
参数指定,默认值是10sKubernetes Controller Manager
定期的检查kubelet
状态,该参数由–-node-monitor-period
参数指定,默认值5sKubernetes Controller Manager
对kubelet
状态更新有一个容忍值,如果kubelet
在这个容忍值内更新状态,那么Kubernetes Controller Manager
认为kubelet
状态有效.容忍值参数由--node-monitor-grace-period
指定,默认值为40sKubernetes Controller Manager
和kubelet
异步工作,这意味着延迟可能包含网络延迟,API Server延迟,etcd延迟,节点负载等引起的延迟,所以如果设置--node-status-update-frequency
参数为5秒时,那么当etcd无法将数据提交到仲裁节点时,它可能会在etcd中等待6-7秒甚至更长才能被呈现
失败
kubelet
将尝试发送nodeStatusUpdateRetry
,当前nodeStatusUpdateRetry
在kubelet.go.中设置为5
kubelet
将使用tryUpdateNodeStatus
方法发送状态.kubelet
使用golang的http.Client()方法,但是没指定超时时长,因此当在apiserver
过载时TCP连接会造成一些问题.- 因此,这里尝试使用
nodeStatusUpdateRetry
乘以--node-status-update-frequency
的值设置node状态. - 在同时
Kubernetes Controller Manager
每隔--node-monitor-period
设置的时间检查nodeStatusUpdateRetry
设置的次数,经过--node-monitor-grace-period
设定的时间将认为node不健康,通过在kube-apiserver
组件中设置--default-not-ready-toleration-seconds
&--default-unreachable-toleration-seconds
这两个默认的容忍参数。Kubernetes
会自动为每个pod
添加一个默认容忍配置,默认容忍限制为60s。在添加这两个参数后需要重新部署所有Pod
以确保将容忍添加到所有Pod
中。除了使用kube-apiserver
的参数使其对所有pod
进行全局更改之外你还可以指定为pod
设置忍驱逐时间 详情请看点击。 - 同时
Kube-Proxy
watchAPI server
,一旦pod被删除,那么集群中所有kube-proxy
将更新其节点上的iptables规则,移除相应的endpoint
,这使得请求无法被发送到故障节点的pod
针对不同案例的建议
社区默认的配置(参数所属组件)
参数 | 值 | 组件 |
---|---|---|
--node-status-update-frequency |
10s | kubelet |
--node-monitor-period |
5s | controller manager |
--node-monitor-grace-period |
40s | controller manager |
快速更新和快速响应
参数 | 值 | 组件 |
---|---|---|
--node-status-update-frequency |
4s | kubelet |
--node-monitor-period |
2s | controller manager |
--node-monitor-grace-period |
20s | controller manager |
如果
--node-status-update-frequency
设置为4s(默认为10s)。--node-monitor-period
设置为2s(默认为5s)。--node-monitor-grace-period
设置20s(默认为40s)。--default-not-ready-toleration-seconds
&--default-unreachable-toleration-seconds
设置为30(默认为 300 秒)。请注意,这两个值应该是表示秒数的整数。
在这种情况下,Pod 将在 50s 后被驱逐,因为节点将在 20s 后被视为Down掉了,
--default-not-ready-toleration-seconds
或者--default-unreachable-toleration-seconds
在 30s 之后开始删除Pod。但是,这种情况会给 etcd 产生很大的开销,因为每个节点都会每 2s 更新一次状态。
如果环境有1000个节点,那么每分钟将有15000次节点更新操作,这可能需要大型 etcd 容器甚至是 etcd 的专用节点。
如果我们计算尝试次数,则除法将给出5,但实际上每次尝试的 nodeStatusUpdateRetry 尝试将从3到5。 由于所有组件的延迟,尝试总次数将在15到25之间变化。
中等更新和平均响应
参数 | 值 | 组件 |
---|---|---|
--node-status-update-frequency |
20s | kubelet |
--node-monitor-period |
5s | controller manager |
--node-monitor-grace-period |
2m | controller manager |
我们设置
--node-status-update-frequency
设置为20s。--node-monitor-grace-period
设置为2m,并将--default-not-ready-toleration-seconds
和--default-unreachable-toleration-seconds
设置为60s。这种场景下会 20s 更新一次 node 状态,Kubernetes Controller Manager
对kubelet
检测,在2分钟内进行 6 * 5 = 30 次尝试如果没有更新节点状态。1m后它将驱逐所有 pod。那么将在一分钟后驱逐所有pod总共耗时3分钟。
此处情况适用于中等环境,因为1000个节点每分钟需要对etcd进行3000次更新。
低更新和慢响应
参数 | 值 | 组件 |
---|---|---|
--node-status-update-frequency |
1m | kubelet |
--node-monitor-period |
5s | controller manager |
--node-monitor-grace-period |
5m | controller manager |
如果
--node-status-update-frequency
设置为1m。--node-monitor-grace-period
设置为5m,并将--default-not-ready-toleration-seconds
和--default-unreachable-toleration-seconds
设置为60s。在这种情况下kubelet
将在每分钟上报状态,5分钟内kubelet
没有更新节点状态Kubernetes Controller Manager
将节点设置为不健康,在一分钟后开始驱逐所有pod总共耗时6分钟。
计算公式
--node-monitor-grace-period
+ --default-not-ready-toleration-seconds
或 --default-unreachable-toleration-seconds
= 驱逐时间
可以有不同的组合,例如快速更新和慢反应以满足特定情况。
原文链接: https://github.com/kubernetes-sigs/kubespray/blob/master/docs/kubernetes-reliability.md