k8s中驱逐pod的详细记录

1.问题

最近dev和beta环境中有几个pod频繁被killed掉重启,检查相关pod都是如下提示

      Reason:       Error
      Exit Code:    137
      Started:      Thu, 21 Dec 2023 14:38:39 +0800
      Finished:     Fri, 22 Dec 2023 11:58:47 +0800

如果是显示 Reason:OOMKilled则是资源超过了Limit被干掉;但是这种Reason:Error,Exit Code:137,查看停止前pod日志都是正常的,大概率也是k8s干掉的,可能是节点资源不足导致被killed然后重新调度。

 通过describe pod的信息可以看到,这几个pod都是在一个节点,21号和22号都出现被killed问题,describe这个node节点可以看到节点的内存不足,触发reclaim内存。

因为当时没有记录内存情况的截图 ,只能查询历史的监控信息,历史监控信息颗粒度因为时间长就变得大了,像这2个时间点(21号14:38分和22号11:57分 腾讯的监控数据存在延迟所以取45分左右的)的应该已经到80%了,但是:为什么到80%就触发了节点去reclaim呢?为什么触发reclaimd会导致该节点的4-5个微服务都重启呢?

 2.k8s节点的压力驱逐

查看k8s官方文档关于节点压力驱逐的

节点压力驱逐 | Kubernetes 

节点压力驱逐涉及节点的内存、磁盘空间和文件系统的 inode 等资源,某个或是多个资源不足会触发k8s回收资源。由上面describe node我们知道,此次的reclaim是因为内存的问题导致的。那节点的哪些配置和内存相关呢?查看官网文档信息

为系统守护进程预留计算资源 | Kubernetes

从这张图可以看出 pod真正能使用的是allocatable这些内存。describe node可以看到信息

查看该节点的kubelet配置

 

--eviction-hard=nodefs.available<10%,nodefs.inodesFree<5%,imagefs.available<15%,memory.available<100Mi

--kube-reserved=cpu=200m,memory=2662Mi 

该节点仅配置了--eviction-hard和kube-reserved,没有system-reserved。则最终能够给pod使用的是: Capacity - 100Mi - 2662Mi = Allocatable(经过计算机计算大概是82%)

结合官网文档的例子

也就是说我这个节点的内存超过82%时,kubelet就会触发pod了,这也解释了第一个问题为什么80%多就开始reclaimd内存。

3.kubelet的evicted分析 

 这时候就想kubelet是如何reclaim的?又是如何驱逐pod重新调度的?

通过官网了解到,驱逐pod是分优先级的(不能单纯的考虑QoS类)

补充下什么是QoS类

 QoS(Quality of Servcie)是针对POD来定义的,描述了POD在被调度和驱逐时的优先顺序,它对POD的生命周期有直接的影响。POD的QoS类别有三种,分别是Guaranteed、Burstable和BestEffort。

上述描述和图引自:一文读懂k8s中的QoS机制 - 掘金 (juejin.cn)

了解了kubelet驱逐pod的大致流程后,被驱逐的几个pod我这里都是设置了request和limit,不过不相等的,都属于Burstable类型的;但是同个节点上也存在未设置request和limit的pod,那为何不优先驱逐未设置资源的pod呢?这就需要了解kubelet详细的驱逐pod的过程(不能单纯的利用QoS类确定驱逐顺序,在回收内存等资源时,你可以使用 QoS 类来估计最可能的 Pod 驱逐顺序。),源码是如何实现的呢?

 顺着这个思路继续排查。

查看kubelet相关日志可以看到,22号11点多频繁的进行reclaim回收资源。

根据日志的输出,我们可以找去查看kubelet的源码相关片段进行分析

关于kubelet驱逐部分源码可以参考:kubelet 驱逐源码分析 - 知乎 

 kubelet回收资源不足了,触发了reclaim

继续分析源码的驱逐流程,这里的8说【8.对不同阈值驱逐场景下pod有不同的排序,比如如果是mem驱逐,就是按照req limit的qos进行排序驱逐】但是感觉应该还有其他因素

 

可以看到排序后的驱逐顺序:

 

这里我简单得进行排序,1-pod和22-pod的request和limit是相同的设置,5-pod是没有设置req和limit,为什么被排在第一位的不是5-pod呢?而且1-pod和22-pod为什么不是排在一起呢,所以对于【8.对不同阈值驱逐场景下pod有不同的排序,比如如果是mem驱逐,就是按照req limit的qos进行排序驱逐】说的这个说法我是不赞同的。这个排序不单纯的取QoS类。还得从官网这句话找排序的原因

大概率就是1的pod设置的req和limit

   Limits:
      cpu:     2
      memory:  2500Mi
    Requests:
      cpu:      100m
      memory:   100Mi

 而其实际1-pod使用内存远高于req的,而22-pod的则不会,所以被排在第一位驱逐。

排序完后可以看到1-pod是被驱逐了

但是后面的日志可以看到, 又被调度回到了这个节点(这个原因主要是因为dev和beta的节点资源不足,重新调度打分是这个节点最高分又被调度回来了),然后调度回这个节点,刚好又到了monitoringInterval,又重新reclaim反反复复,最终使得CPU直接爆掉,在这个节点存在3-4个pod是健康检查和就绪性检查的,CPU爆满导致进程卡死,健康检查多次不通过,pod重启,这也解释了前面的疑问为什么节点会有4-5个微服务重启。

 

总结:

及时了解节点使用情况,进行动态扩容;

pod中req和limit的正确配置。 

  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值