Eviction驱逐介绍

kubelet主动监测和防止Kubernetes集群的资源使用情况,在资源短缺时,如何判断资源短缺根据系统设置的eviction保留策略,当节点资源使用触发到该阈值,开始执行驱逐(主动的结束一个或者多个Pod以回收资源,Pod的状态变为Failed),如果被驱逐的Pod被deployment控制器接管,那么将会被调度到其它的节点

  • 可压缩资源 —— cpu,可压缩资源不会导致pod驱逐,因为在资源紧缺时系统内核会重新分配权重
  • 不可压缩资源 —— 内存 磁盘

Kubelet Eviction策略工作机制

  • kubelet预先监控本节点的资源使用,防止资源被耗尽,保证节点稳定性
  • kubelet会预先Fail N(>=1)个Pod,以回收出现紧缺的资源
  • kubelet在Fail一个pod时,kill掉pod内所有container,并设置pod.status.phase = Failed
  • kubelet按照事先设定好的Eviction Threshold来触发驱逐动作,实现资源回收

驱逐信号

Eviction SignalDescription
memory.availablenode.status.capacity[memory] -node.stats.memory.workingSet
nodefs.availablenode.stats.fs.available
nodefs.inodesFreenode.stats.fs.inodesFree
imagefs.availablenode.stats.runtime.imagefs.available
imagefs.inodesFreenode.stats.runtime.imagefs.inodesFree
allocatableMemory.availablepod.allocatable - pod.workingSet
pid.availablenode.MaxPID - node.NumOfRunningProcesses

上表主要涉及三个方面,memory、file system和pid
其中kubelet支持2种file system类型的驱逐:
nodefs:kubelet 用来存储 pods 或 volume 和 daemon logs 的信息等
Imagesfs:用来存储 docker 镜像层或容器层数据的路径(readOnly layer and write layer)

驱逐策略

k8s中定义了两种驱逐策略,一种为软驱逐,一种为硬驱逐

软驱逐(Soft Eviction Thresholds)

软驱逐机制表示,当node的内存/磁盘空间达到一定的阈值后,我们要观察一段时间,如果改善到低于阈值就不进行驱逐,若这段时间一直高于阈值就进行驱逐
一般由三个参数配合使用:

  • eviction-soft:触发软驱逐策略的阀值
  • eviction-soft-grace-period:触发软驱逐策略的阀值后等待的时间,如果在此时间内还未恢复到阀值以下,则会开始驱逐pod
  • eviction-max-pod-grace-period:达到软阈值之后,到驱逐一个 Pod 之前的最大宽限时间(单位 s )

硬驱逐(Hard Eviction Thresholds)

硬驱逐简单粗暴,没有宽限期,一旦达到阈值配置,kubelet立马回收关联的短缺资源,将pod kill掉,而不是优雅终止
源码pkg/kubelet/apis/config/v1beta1/defaults_linux.go给出了默认的硬驱逐配置:

  • memory.available < 100Mi
  • nodefs.available < 10%
  • nodefs.inodesFree < 5%
  • imagefs.available < 15%

Pod驱逐流程

当资源使用情况触发了驱逐条件时,kubelet会启动一个任务去轮流停止运行中的pod,直到资源使用状况恢复到阈值以下,以硬驱逐为例,整体流程是:

  1. 每隔一段时间从cadvisor中获取资源使用情况,和定义的阀值进行对比,在 kubelet 中 --node-status-update-frequency 参数来定义获取上报的频率,默认为10s
  2. 首先从运行中的pod里找到QoS策略最开放的类型 pod ,然后根据 Pod 调度请求的被耗尽资源的消耗量来结合进行驱逐
  3. 检查资源是否到达阀值以内,若还未满足,则再进行第二步

Qos驱逐等级

当一个pod被创建,kubernetes会赋予它们以下类型的值之一

  • Guaranteed
  • Burstable
  • BestEffor
    三种Qos类型优先级(由高到低):Guaranteed > Burstable > BestEffort
    从上到下,它们的质量会越来越低,质量越高,该pod就会尽量被保护,不被驱逐

满足以下条件的pod将会被赋予 Guaranteed QoS类型

  • pod中每个容器都必须包含内存请求和限制,并且值相等
  • pod中每个容器都必须包含cpu请求和限制,并且值相等

当符合以下条件时,一个pod会被赋予Burstable类型的QoS

  • Pod不符合 Guaranteed 类型的QoS要求
  • pod至少设置了内存或者cpu请任一

一个pod即没有内存限制或请求也没有cpu限制或请求,则会被赋予BestEffort
查看某pod的qos等级:

[root@k8s01 ~]# kubectl get -n kube-system pod coredns-5cf6c68f7f-p6glg -oyaml|grep qos
  qosClass: Burstable

资源紧缺时,驱逐pod的优先级规则

  • 当 pod qos=BestEffort 时,消耗最多紧缺资源的 Pod 最先驱逐
  • 当 pod qos=Burstable 时,请求(request的值)最多紧缺资源的 Pod 会被驱逐,如果没有 Pod 超出他们的请求(比如说mem request的值为1G,但实际使用量并没有超过1G),会驱逐资源消耗量最大的 Pod
  • 当 pod qos=Guaranteed 时,请求(request的值)最多紧缺资源的 Pod 被驱逐,如果没有 Pod 超出他们的请求,会驱逐资源消耗量最大的 Pod

如果当磁盘空间/inodes紧缺时,就会通过 QoS 的等级基础上,选择消耗最多磁盘空间inodes的 Pod 进行驱逐

问题拓展

如何更改kubelet的默认驱逐阀值

硬阀值的设置

将以下策略加入到/opt/kubernetes/cfg/kubelet.conf即kublet启动参数即可

...
--eviction-hard=memory.available<256Mi,nodefs.available<1Gi,imagefs.available<1Gi \
--eviction-minimum-reclaim=memory.available=512Mi,nodefs.available=1Gi,imagefs.available=1Gi \
--eviction-pressure-transition-period=30s
...

第一行表示当memory<256Mi,nodefs<1G,imagesfs<1G,时才会触发硬驱逐策略
第二行表示最小驱逐回收策略,就是一旦驱逐策略被触发,则要一直驱逐直到低于此行策略的阀值为止,为了就是防止刚刚触发硬驱逐策略,驱逐完之后没一会资源又涨上来了,导致要反复驱逐的现象
第三行是为了防止node节点状态振荡

软阀值的设置

...
--eviction-soft=memory.available<10%,nodefs.available<15%,imagefs.available<15% \
--eviction-soft-grace-period=memory.available=2m,nodefs.available=2m,imagefs.available=2m \
--eviction-max-pod-grace-period=30
...

第一行表示软驱逐阀值,使用百分比代替
第二行表示触发软驱逐后,等待执行的时间,若此时间内低于阀值,则不再进行驱逐
第三行为pod宽限时间

当资源不够或发生争夺有pod被驱逐后,pod的状态会变为Eviction,如果资源一直无法协调过来,或者资源真的不够用了,那么会产生大量的Eviction状态的Pod,会影响整个集群的使用,如何限制Eviction的Pod的数量

此配置其实是由 kube-contoller-manager来管理的,所以想要修改要修改kube-contoller-manager的参数,一般在/opt/kubernetes/cfg/kube-controller-manager.conf

...
--terminated-pod-gc-threshold=1 \
...

此值设定了Eviction pod最大的产生个数,默认为12500,最小改为1,若为0,则表示没有限制

文章作者: 鲜花的主人
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 爱吃可爱多
Kubernetes Kubernetes
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝