Redian新闻
>
记录一次 K8s pod 被杀的排查过程

记录一次 K8s pod 被杀的排查过程

公众号新闻

链接:https://www.cnblogs.com/xtf2009/p/17947545

问题描述

今天下午运维反馈说我们这一个pod一天重启了8次,需要排查下原因。一看Kiban日志,jvm没有抛出过任何错误,服务就直接重启了。显然是进程被直接杀了,初步判断是pod达到内存上限被K8s oomkill了。
因为我们xmx和xsx设置的都是3G,而pod的内存上限设置的是6G,所以出现这种情况还挺诡异的。

排查过程

初步定位

先找运维拉了一下pod的描述,关键信息在这里

Containers:
container-prod--:
Container ID: --
Image: --
Image ID: docker-pullable://--
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 05 Jan 2024 11:40:01 +0800
Last State: Terminated
Reason: Error
Exit Code: 137
Started: Fri, 05 Jan 2024 11:27:38 +0800
Finished: Fri, 05 Jan 2024 11:39:58 +0800
Ready: True
Restart Count: 8
Limits:
cpu: 8
memory: 6Gi
Requests:
cpu: 100m
memory: 512Mi
  • 可以看到Last State:Terminated,Exit Code: 137。这个错误码表示的是pod进程被SIGKILL给杀掉了。一般情况下是因为pod达到内存上限被k8s杀了。
    因此得出结论是生产环境暂时先扩大下pod的内存限制,让服务稳住。然后再排查为啥pod里会有这么多的堆外内存占用。

进一步分析

但是运维反馈说无法再扩大pod的内存限制,因为宿主机的内存已经占到了99%了。
然后结合pod的内存监控,发现pod被杀前的内存占用只到4G左右,没有达到上限的6G,pod就被kill掉了。

于是问题就来了,为啥pod没有达到内存上限就被kill了呢。
带着疑问,我开始在google里寻找答案,也发现了一些端倪:

  • 如果是pod内存达到上限被kill,pod的描述里会写Exit Code: 137,但是Reason不是Error,而是OOMKilled

  • 宿主机内存已经吃满,会触发k8s的保护机制,开始evict一些pod来释放资源

  • 但是为什么整个集群里,只有这个pod被反复evict,其他服务没有影响?

谜题解开

最终还是google给出了答案:
Why my pod gets OOMKill (exit code 137) without reaching threshold of requested memory

链接里的作者遇到了和我一样的情况,pod还没吃到内存上限就被杀了,而且也是:

  Last State:     Terminated
Reason: Error
Exit Code: 137

作者最终定位的原因是因为k8s的QoS机制,在宿主机资源耗尽的时候,会按照QoS机制的优先级,去杀掉pod来释放资源。

什么是k8s的QoS?

QoS,指的是Quality of Service,也就是k8s用来标记各个pod对于资源使用情况的质量,QoS会直接影响当节点资源耗尽的时候k8s对pod进行evict的决策。官方的描述在这里.

k8s会以pod的描述文件里的资源限制,对pod进行分级:

QoS条件
Guaranteed1. pod里所有的容器都必须设置cpu和内存的request和limit,2. pod里所有容器设置的cpu和内存的request和容器设置的limit必须相等(容器自身相等,不同容器可以不等)
Burstable1. pod并不满足Guaranteed的条件,2. 至少有一个容器设置了cpu或者内存的request或者limit
BestEffortpod里的所有容器,都没有设置任何资源的request和limit

当节点资源耗尽的时候,k8s会按照BestEffort->Burstable->Guaranteed这样的优先级去选择杀死pod去释放资源。

从上面运维给我们的pod描述可以看到,这个pod的资源限制是这样的:

    Limits:
cpu: 8
memory: 6Gi
Requests:
cpu: 100m
memory: 512Mi

显然符合的是Burstable的标准,所以宿主机内存耗尽的情况下,如果其他服务都是Guaranteed,那自然会一直杀死这个pod来释放资源,哪怕pod本身并没有达到6G的内存上限。

QoS相同的情况下,按照什么优先级去Evict?

但是和运维沟通了一下,我们集群内所有pod的配置,limit和request都是不一样的,也就是说,大家都是Burstable。所以为什么其他pod没有被evict,只有这个pod被反复evict呢?

QoS相同的情况,肯定还是会有evict的优先级的,只是需要我们再去寻找下官方文档。

关于Node资源耗尽时候的Evict机制,官方文档有很详细的描述。

其中最关键的一段是这个:

If the kubelet can't reclaim memory before a node experiences OOM, the oom_killer calculates an oom_score based on the percentage of memory it's using on the node, and then adds the oom_score_adj to get an effective oom_score for each container. It then kills the container with the highest score.

This means that containers in low QoS pods that consume a large amount of memory relative to their scheduling requests are killed first.

简单来说就是pod evict的标准来自oom_score,每个pod都会被计算出来一个oom_score,而oom_score的计算方式是:pod使用的内存占总内存的比例加上pod的oom_score_adj值

oom_score_adj的值是k8s基于QoS计算出来的一个偏移值,计算方法:

QoSoom_score_adj
Guaranteed-997
BestEffort1000
Burstablemin(max(2, 1000 - (1000 × memoryRequestBytes) / machineMemoryCapacityBytes), 999)
从这个表格可以看出:首先是BestEffort->Burstable->Guaranteed这样的一个整体的优先级然后都是Burstable的时候,pod实际占用内存/pod的request内存比例最高的,会被优先Evict

总结

至此已经可以基本上定位出Pod被反复重启的原因了:

k8s节点宿主机内存占用满了,触发了Node-pressure Eviction按照Node-pressure Eviction的优先级,k8s选择了oom_score最高的pod去evict由于所有pod都是Burstable,并且设置的request memery都是一样的512M,因此内存占用最多的pod计算出来的oom_score就是最高的所有pod中,这个服务的内存占用一直都是最高的,所以每次计算出来,最后都是杀死这个pod
  • 那么如何解决呢?

  • 宿主机内存扩容,不然杀死pod这样的事情无法避免,无非就是杀哪个的问题

  • 对于关键服务的pod,要把request和limit设置为完全一致,让pod的QoS置为Guaranteed,尽可能降低pod被杀的几率

    END

    官方站点:www.linuxprobe.com

    Linux命令大全:www.linuxcool.com

    刘遄老师QQ:5604215

    Linux技术交流群:2636170

    (新群,火热加群中……)

    想要学习Linux系统的读者可以点击"阅读原文"按钮来了解书籍《Linux就该这么学》,同时也非常适合专业的运维人员阅读,成为辅助您工作的高价值工具书!


    微信扫码关注该文公众号作者

    戳这里提交新闻线索和高质量文章给我们。
    相关阅读
    4个公租房小区排查出766户公职人员!最新进展:已腾退五六百户,将再摇号分配一个绝顶聪明的排长,被美军逼到无路可退,最后的时刻他会想什么孩子给同学误食washing pod警惕!澳女花$550买电视,惨遭诈骗!监控视频记录全过程深度好文|恰逢印度每年最重要的排灯节,来聊聊面试时如何卷赢其他国家对手…【精选】亚洲top50酒吧来多伦多、薯条界的排行榜、功夫熊猫4首映礼花絮……华府消息|拜登称已做出如何回应美军人员被杀的决定 伊朗表示如遇袭将果断反击支持百亿参数大模型、卢伟冰现场官宣小米首发,高通骁龙8s Gen3发布骁龙最强AI芯能力下放:小旗舰8s发布,端侧运行10B大模型,小米Civi首发一文带你Ranther管理K8S集群不敢把数据库运行在 K8s 上?容器化对数据库性能有影响吗?席琳·迪翁最新纪录片制作完成,记录其与罕见病抗争过程波士顿24Fall | 步行上学的排队抢房已经开始 免中介费火热排队/预订中!附最新小居探楼实拍k8s中磁盘空间清理以及垃圾回收机制你知道吗一篇可供参考的 K8S 落地实践经验一幅难忘的小说插图2023年全球最安全与最危险地区排行榜出炉!赶紧来看看新西兰的排名恰逢印度每年最重要的排灯节,来聊聊面试时如何卷赢其他国家对手…四张图表解读印度股市与港股的排位战美国放宽了汽车的排放限制,为啥他们搞不来新能源?K8s容器debug高级技巧家居自己做过的事系列:电工(1)假如有一分钟在狂笑时间复杂度为O (nlogn)的排序算法小米Civi4 Pro首发8s Gen3;vivo折叠屏新品官宣;工信部:遏制电动车盲目投资K8s部署Jumpserver并使用Istio对外暴露服务真实记录:51岁女性安乐死全过程,从清醒到死亡,她只用了4分钟命运组合论 第一章 绪论 第二节12月起禁用这种灯!各地提前展开排查老钱:“不须放屁”记录一次K8s pod被杀的排查过程三大量化私募被查暂停备案?多方紧急回应!部分私募排查底层资产主人记录狗狗成长全过程​,超治愈!​国家安全机关:开展地理信息数据安全风险专项排查治理从物理机到K8S:应用系统部署方式的演进及其影响汪小姐带火的排骨年糕,是多少上海人的青春?
    logo
    联系我们隐私协议©2024 redian.news
    Redian新闻
    Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。