共计 6398 个字符,预计需要花费 16 分钟才能阅读完成。
这篇文章主要讲解了“Kubernetes Eviction Manager 工作机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着丸趣 TV 小编的思路慢慢深入,一起来研究和学习“Kubernetes Eviction Manager 工作机制是什么”吧!
首先,我们来谈一下 kubelet 通过 OOM Killer 来回收资源的缺点:
System OOM events 本来就是对资源敏感的,它会 stall 这个 Node 直到完成了 OOM Killing Process。
当 OOM Killer 干掉某些 containers 之后,kubernetes Scheduler 可能很快又会调度一个新的 Pod 到该 Node 上或者 container 直接在 node 上 restart,马上又会触发该 Node 上的 OOM Killer 启动 OOM Killing Process,事情可能会没完没了的进行,这可不妙啊。
我们再来看看 Kubelet Eviction 有何不同:
Kubelet 通过 pro-actively 监控并阻止 Node 上资源的耗尽,一旦触发 Eviction Signals,就会直接 Fail 一个或者多个 Pod 以回收资源,而不是通过 Linux OOM Killer 这样本身耗资源的组件进行回收。
这样的 Eviction Signals 的可配置的,可以做到 Pro-actively。
另外,被 Evicted Pods 会在其他 Node 上重新调度,而不会再次触发本 Node 上的再次 Eviction。
下面,我们具体来研究一下 Kubelet Eviction Policy 的工作机制。
kubelet 预先监控本节点的资源使用,并且阻止资源被耗尽,这样保证 node 的稳定性。
kubelet 会预先 Fail N(= 1)个 Pod 以回收出现紧缺的资源。
kubelet 会 Fail 一个 Node 时,会将 Pod 内所有 Containners 都 kill 掉,并把 PodPhase 设为 Failed。
kubelet 通过事先人为设定 Eviction Thresholds 来触发 Eviction 动作以回收资源。
Eviction Signals
支持如下 Eviction Signals:
Eviction SignalDescriptionmemory.availablememory.available := node.status.capacity[memory] – node.stats.memory.workingSetnodefs.availablenodefs.available := node.stats.fs.availablenodefs.inodesFreenodefs.inodesFree := node.stats.fs.inodesFreeimagefs.availableimagefs.available := node.stats.runtime.imagefs.availableimagefs.inodesFreeimagefs.inodesFree := node.stats.runtime.imagefs.inodesFree
kubelet 目前支持一下两种 filesystem,其中 imagefs 为可选的。Kubelet 通过 cAdvisor 来自动发现这些 filesystem。
nodefs – Kubelet 用来存储 volume,logs 等数据。
imagefs – 容器运行时 (dockerd/rkt 等) 用来存放镜像和容器的 Writable Layer。
Eviction Thresholds
前面也提到,kubelet 通过事先人为设定 Eviction Thresholds 来触发 Eviction 动作以回收资源。
Eviction Thresholds 的形式为:eviction-signal operator quantity
quantity 支持绝对值和相对百分比两种形式,比如:
memory.available 10%
memory.available 1Gi
Soft Eviction Thresholds
Soft Eviction Thresholds 是什么意思?它指的是,当 Eviction Signal 中值达到 Soft Eviction Thresholds 配置的值时,并不会马上触发 Kubelet 去 Evict Pods,而是会等待一个用户配置的 grace period 之后,再触发。相关的配置有三个,如下:
eviction-soft – (e.g. memory.available 1.5Gi) 触发 Soft Eviction 的 Evication Signal 阈值。
eviction-soft-grace-period – (e.g. memory.available=1m30s) 当 Eviction Signal 的值达到配置 eviction-soft 值后,需要等待 grace period,注意这期间,每 10s 会重新获取监控数据并维护 Threshold 的值。如果 grace period 最后一次监控数据仍然触发了阈值,才会再触发 Evict Pods。这个参数就是配置这个 grace period 的。
eviction-max-pod-grace-period – (e.g. memory.available=30s) 这个是配置 Evict Pods 时,Pod Termination 的 Max Grace Period。如果待 Evict 的 Pod 指定了 pod.Spec.TerminationGracePeriodSeconds,则取 min(eviction-max-pod-grace-period, pod.Spec.TerminationGracePeriodSeconds)作为 Pod Termination 真正的 Grace Period。
因此,从 kubelet 监控到的 Eviction Signal 达到指定的 Soft Eviction Thresholds 开始,到 Pod 真正被 Kill,总共所需要的时间为:sum(eviction-soft-grace-period + min(eviction-max-pod-grace-period, pod.Spec.TerminationGracePeriodSeconds))
Hard Eviction Thresholds
理解了 Soft Eviction Thresholds, 那么 Hard Eviction Thresholds 就很简单了,它是指:当 Eviction Signal 中值达到 Hard Eviction Thresholds 配置的值时,会立刻触发 Kubelet 去 Evict Pods,并且也不会有 Pod Termination Grace Period,而是立刻 kill Pods,即使待 Evict 的 Pod 指定了 pod.Spec.TerminationGracePeriodSeconds。
总之,Hard Eviction Thresholds 就是来硬的,一旦触发,kubelet 立刻马上 kill 相关的 pods。
因此,kubelet 关于 Hard Eviction Thresholds 的配置也只有一个:
eviction-hard – (e.g. memory.available 1Gi) 这个值,要设置的比 eviction-soft 更低才有意义。
Eviction Monitoring Interval
kubelet 会通过监控 Eviction Signal 的值,当达到配置的阈值时,就会触发 Evict Pods。kubelet 对应的监控周期,就通过 cAdvisor 的 housekeeping-interval 配置的,默认 10s。
Node Conditions
当 Hard Eviction Thresholds 或 Soft Eviction Thresholds 被触及后,Kubelet 会将对应的 Eviction Signals 映射到对应的 Node Conditions,其映射关系如下:
Node ConditionEviction SignalDescriptionMemoryPressurememory.availableAvailable memory on the node has satisfied an eviction thresholdDiskPressurenodefs.available, nodefs.inodesFree, imagefs.available, or imagefs.inodesFreeAvailable disk space and inodes on either the node s root filesystem or image filesystem has satisfied an eviction threshold
kubelet 映射了 Node Condition 之后,会继续按照 –node-status-update-frequency(default 10s)配置的时间间隔,周期性的与 kube-apiserver 进行 node status updates。
Oscillation of node conditions
想象一下,如果一个 Node 上监控到的 Soft Eviction Signals 的值,一直在 eviction-soft 水平线上下波动,那么 Kubelet 就会将该 Node 对应的 Node Condition 在 true 和 false 频繁切换。这可不是什么好事,它可能会带来 kube-scheduler 做出错误的调度决定。kubelet 是怎么处理这种情况的呢?
很简单,Kubelet 通过添加参数 eviction-pressure-transition-period(default 5m0s)配置,使 Kubelet 在解除由 Evicion Signal 映射的 Node Pressure 之前,必须等待这么长的时间。
因此,逻辑就变成这样了:
Soft Evction Singal 高于 Soft Eviction Thresholds 时,Kubelet 还是会立刻设置对应的 MemoryPressure Or DiskPressure 为 True。
当 MemoryPressure Or DiskPressure 为 True 的前提下,发生了 Soft Evction Singal 低于 Soft Eviction Thresholds 的情况,则需要等待 eviction-pressure-transition-period(default 5m0s)配置的这么长时间,才会将 condition pressure 切换回 False。
一句话总结:Node Condition Pressure 成为 True 容易,切换回 False 则要等 eviction-pressure-transition-period。
Eviction of Pods
Kubelet 的 Eviction 流程概括如下:
在每一个监控周期内,如果 Eviction Thresholds 被触及,则:
获取候选 Pod
Fail the Pod
等待该 Pod 被 Terminated 如果该 Pod 由于种种原因没有被成功 Terminated,Kubelet 将会再选一个 Pod 进行 Fail Operation。其中,Fail Pod 的时候,Kubelet 是通过调用容器运行时的 KillPod 接口,如果接口返回 True,则认为 Fail Pod 成功,否则视为失败。
Eviction Strategy
kubelet 根据 Pod 的 QoS Class 实现了一套默认的 Evication 策略,内容见我的另外一篇博文 Kubernetes Resource QoS 机制解读中介绍的“如何根据不同的 QoS 回收 Resource”, 这里不再赘述。
下面给出 Eviction Strategy 的图解:
Minimum eviction reclaim
有些情况下,eviction pods 可能只能回收一小部分的资源就能使得 Evication Signal 的值低于 Thresholds。但是,可能随着资源使用的波动或者新的调度 Pod 使得在该 Node 上很快又会触发 evict pods 的动作,eviction 毕竟是耗时的动作,所以应该尽量避免这种情况的发生。
Kubelet 是通过 –eviction-minimum-reclaim(e.g. memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi)来控制每次 Evict Pods 后,Node 上对应的 Resource 不仅要比 Eviction Thresholds 低,还要保证最少比 Eviction Thresholds 低 –eviction-minimum-reclaim 中配置的数量。
Node OOM Behavior
正常情况下,但 Node 上资源利用率很高时,Node 的资源回收是会通过 Kubelet Eviction 触发完成。但是存在这么一种情况,Kubelet 配置的 Soft/Hard memory.available 还没触发,却先触发了 Node 上 linux kernel oom_killer,这时回收内存资源的请求就被 kernel oom_killer 处理了,而不会经过 Kubelet Eviction 去完成。
我的博文 Kubernetes Resource QoS 机制解读中介绍过,Kubelet 根据 Pod QoS 给每个 container 都设置了 oom_score_adj,整理如下:
Quality of Serviceoom_score_adjGuaranteed-998BestEffort1000Burstablemin(max(2, 1000 – (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
oom_killer 根据 container 使用的内存占 Node 总内存的百分比计算得到该 container 的 oom_score,然后再将该 oom_sore 和前面对应的 oom_score_adj 相加作为最终的 oom_score,Node 上所有 containers 的最终 oom_score 进行排名,将 oom_score 得分最高的 container kill 掉。通过如此方式进行资源回收。
oom_killer 这样做的目标就是干掉 QoS 低的又消耗最多内存 (相对 request 值) 的容器首先被 kill 掉,如此回收内存。
不同于 Kubelet Evict Pods 的是,Node OOM Behavior 存在一个缺点:如果 Pod 中某个容器被 oom_killer 干掉之后,会根据该容器的 RestartPolicy 决定是否 restart 这个容器。如果这是个有问题的容器,restart 之后,可能又很快消耗大量内存进而触发了再次 Node OOM Behavior,如此循环反复,该 Node 没有真正的回收到内存资源。
Scheduler
前面提到,Kubelet 会定期的将 Node Condition 传给 kube-apiserver 并存于 etcd。kube-scheduler watch 到 Node Condition Pressure 之后,会根据以下策略,阻止更多 Pods Bind 到该 Node。
Node ConditionScheduler BehaviorMemoryPressureNo new BestEffort pods are scheduled to the node.DiskPressureNo new pods are scheduled to the node.
感谢各位的阅读,以上就是“Kubernetes Eviction Manager 工作机制是什么”的内容了,经过本文的学习后,相信大家对 Kubernetes Eviction Manager 工作机制是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是丸趣 TV,丸趣 TV 小编将为大家推送更多相关知识点的文章,欢迎关注!