这篇文章主要讲解了“Kubernetes Eviction Manager工作机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“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 Signal | Description |
---|---|
memory.available | memory.available := node.status.capacity[memory] - node.stats.memory.workingSet |
nodefs.available | nodefs.available := node.stats.fs.available |
nodefs.inodesFree | nodefs.inodesFree := node.stats.fs.inodesFree |
imagefs.available | imagefs.available := node.stats.runtime.imagefs.available |
imagefs.inodesFree | imagefs.inodesFree := node.stats.runtime.imagefs.inodesFree |
kubelet目前支持一下两种filesystem,其中imagefs为可选的。Kubelet通过cAdvisor来自动发现这些filesystem。
nodefs - Kubelet用来存储volume,logs等数据。
imagefs - 容器运行时(dockerd/rkt等)用来存放镜像和容器的Writable Layer。
前面也提到,kubelet通过事先人为设定Eviction Thresholds来触发Eviction动作以回收资源。
Eviction Thresholds的形式为:<eviction-signal><operator><quantity>
quantity
支持绝对值和相对百分比两种形式,比如:
memory.available<10%
memory.available<1Gi
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))
理解了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
更低才有意义。
kubelet会通过监控Eviction Signal的值,当达到配置的阈值时,就会触发Evict Pods。 kubelet对应的监控周期,就通过cAdvisor的housekeeping-interval
配置的,默认10s。
当Hard Eviction Thresholds
或Soft Eviction Thresholds
被触及后,Kubelet会将对应的Eviction Signals映射到对应的Node Conditions,其映射关系如下:
Node Condition | Eviction Signal | Description |
---|---|---|
MemoryPressure | memory.available | Available memory on the node has satisfied an eviction threshold |
DiskPressure | nodefs.available, nodefs.inodesFree, imagefs.available, or imagefs.inodesFree | Available 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。
想象一下,如果一个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
。
Kubelet的Eviction流程概括如下:
在每一个监控周期内,如果Eviction Thresholds被触及,则:
获取候选Pod
Fail the Pod
等待该Pod被Terminated 如果该Pod由于种种原因没有被成功Terminated,Kubelet将会再选一个Pod进行Fail Operation。其中,Fail Pod的时候,Kubelet是通过调用容器运行时的KillPod接口,如果接口返回True,则认为Fail Pod成功,否则视为失败。
kubelet根据Pod的QoS Class实现了一套默认的Evication策略,内容见我的另外一篇博文Kubernetes Resource QoS机制解读中介绍的“如何根据不同的QoS回收Resource”,这里不再赘述。
下面给出Eviction Strategy的图解:
有些情况下,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上资源利用率很高时,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 Service | oom_score_adj |
---|---|
Guaranteed | -998 |
BestEffort | 1000 |
Burstable | min(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没有真正的回收到内存资源。
前面提到,Kubelet会定期的将Node Condition传给kube-apiserver并存于etcd。kube-scheduler watch到Node Condition Pressure之后,会根据以下策略,阻止更多Pods Bind到该Node。
Node Condition | Scheduler Behavior |
---|---|
MemoryPressure | No new BestEffort pods are scheduled to the node. |
DiskPressure | No new pods are scheduled to the node. |
感谢各位的阅读,以上就是“Kubernetes Eviction Manager工作机制是什么”的内容了,经过本文的学习后,相信大家对Kubernetes Eviction Manager工作机制是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。