文档首页> 云容器引擎 CCE> 常见问题> 工作负载> 工作负载异常> 工作负载异常:实例驱逐异常(Evicted)
更新时间:2022-05-06 GMT+08:00
分享

工作负载异常:实例驱逐异常(Evicted)

Eviction介绍

Eviction,即驱逐的意思,意思是当节点出现异常时,为了保证工作负载的可用性,kubernetes将有相应的机制驱逐该节点上的Pod。

目前kubernetes中存在两种eviction机制,分别由kube-controller-managerkubelet实现。

  • kube-controller-manager实现的eviction

    kube-controller-manager主要由多个控制器构成,而eviction的功能主要由node controller这个控制器实现。该Eviction会周期性检查所有节点状态,当节点处于NotReady状态超过一段时间后,驱逐该节点上所有pod。

    kube-controller-manager提供了以下启动参数控制eviction:

    • pod-eviction-timeout:即当节点宕机该时间间隔后,开始eviction机制,驱赶宕机节点上的Pod,默认为5min。
    • node-eviction-rate:驱赶速率,即驱赶Node的速率,由令牌桶流控算法实现,默认为0.1,即每秒驱赶0.1个节点,注意这里不是驱赶Pod的速率,而是驱赶节点的速率。相当于每隔10s,清空一个节点。
    • secondary-node-eviction-rate:二级驱赶速率,当集群中宕机节点过多时,相应的驱赶速率也降低,默认为0.01。
    • unhealthy-zone-threshold:不健康zone阈值,会影响什么时候开启二级驱赶速率,默认为0.55,即当该zone中节点宕机数目超过55%,而认为该zone不健康。
    • large-cluster-size-threshold:大集群阈值,当该zone的节点多余该阈值时,则认为该zone是一个大集群。大集群节点宕机数目超过55%时,则将驱赶速率降为0.01,假如是小集群,则将速率直接降为0。
  • kubelet的eviction机制

    如果节点处于资源压力,那么kubelet就会执行驱逐策略。驱逐会考虑Pod的优先级,资源使用和资源申请。当优先级相同时,资源使用/资源申请最大的Pod会被首先驱逐。

    kube-controller-manager的eviction机制是粗粒度的,即驱赶一个节点上的所有pod,而kubelet则是细粒度的,它驱赶的是节点上的某些Pod,驱赶哪些Pod与Pod的Qos机制有关。该Eviction会周期性检查本节点内存、磁盘等资源,当资源不足时,按照优先级驱逐部分pod。

    驱逐阈值分为软驱逐阈值(Soft Eviction Thresholds)和强制驱逐(Hard Eviction Thresholds)两种机制,如下:

    • 软驱逐阈值:当node的内存/磁盘空间达到一定的阈值后,kubelet不会马上回收资源,如果改善到低于阈值就不进行驱逐,若这段时间一直高于阈值就进行驱逐
    • 强制驱逐:强制驱逐机制则简单的多,一旦达到阈值,直接把pod从本地驱逐。

    kubelet提供了以下参数控制eviction:

    • eviction-soft:软驱逐阈值设置,具有一系列阈值,比如memory.available<1.5Gi时,它不会立即执行pod eviction,而会等待eviction-soft-grace-period时间,假如该时间过后,依然还是达到了eviction-soft,则触发一次pod eviction。
    • eviction-soft-grace-period:默认为90秒,当eviction-soft时,终止Pod的grace的时间,即软驱逐宽限期,软驱逐信号与驱逐处理之间的时间差。
    • eviction-max-pod-grace-period:最大驱逐pod宽限期,停止信号与kill之间的时间差。
    • eviction-pressure-transition-period:默认为5分钟,脱离pressure condition的时间,超过阈值时,节点会被设置为memory pressure或者disk pressure,然后开启pod eviction。
    • eviction-minimum-reclaim:表示每一次eviction必须至少回收多少资源。
    • eviction-hard强制驱逐设置,也具有一系列的阈值,比如memory.available<1Gi,即当节点可用内存低于1Gi时,会立即触发一次pod eviction。

问题定位

若节点故障时,实例未被驱逐,请先按照如下方法进行问题定位。

使用如下命令发现很多pod的状态为Evicted:

kubectl get pods
在节点的kubelet日志中会记录Evicted相关内容,搜索方法可参考如下命令:
cat /var/paas/sys/log/kubernetes/kubelet.log | grep -i Evicted -C3

排查思路

以下排查思路根据原因的出现概率进行排序,建议您从高频率原因往低频率原因排查,从而帮助您快速找到问题的原因。

如果解决完某个可能原因仍未解决问题,请继续排查其他可能原因。

图1 排查思路

排查项一:是否在实例上设置了tolerations

通过kubectl工具或单击对应工作负载后的“更多 > 查看YAML”,检查工作负载上是不是打上了tolerations,具体请参见https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/

排查项二:是否满足停止驱逐实例的条件

若属于小规格的集群(集群节点数小于50个节点),如果故障的节点大于总节点数的55%,实例的驱逐将会被暂停。此情况下k8s将部署尝试驱逐故障节点的工作负载,具体请参见https://kubernetes.io/docs/concepts/architecture/nodes/

排查项三:容器与节点上的“资源分配量”是否一致

容器被驱逐后还会频繁调度到原节点。

问题原因:

节点驱逐容器是根据节点的“资源使用率”进行判断;容器的调度规则是根据节点上的“资源分配量”进行判断。由于判断标准不同,所以可能会出现被驱逐后又再次被调度到原节点的情况。

解决方案:

遇到此类问题时,请合理分配各容器的资源分配量即可解决。

排查项四:工作负载实例不断失败并重新部署

工作负载实例出现不断失败,不断重新部署的情况。

问题分析:

pod驱逐后,如果新调度到的节点也有驱逐情况,就会再次被驱逐;甚至出现pod不断被驱逐的情况。

如果是由kube-controller-manager触发的驱逐,会留下一个状态为Terminating的pod;直到容器所在节点状态恢复后,pod才会自动删除。如果节点已经删除或者其他原因导致的无法恢复,可以使用“强制删除”删除pod。

如果是由kubelet触发的驱逐,会留下一个状态为Evicted的pod,此pod只是方便后期定位的记录,可以直接删除。

解决方案:

使用如下命令删除旧驱赶的遗留:

kubectl get pods <namespace> | grep Evicted | awk '{print $1}' | xargs kubectl delete pod <namespace> 

<namespace>为命名空间名称,请根据需要指定。

提交工单

如果上述方法均不能解决您的疑问,提交工单寻求更多帮助。

分享:

工作负载异常所有常见问题

more

close