一次 K8s Pod 频繁被“驱逐”,结果竟是这样的?

问题描述

某天下午运维反馈说我们这一个pod一天重启了8次,需要排查下原因。一看 Kibana 日志,jvm 没有抛出过任何错误,服务就直接重启了。显然是进程被直接杀了,初步判断是 pod 达到内存上限被 K8s oomkill 了。

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进行分级:

图片

当节点资源耗尽的时候,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 计算出来的一个偏移值,计算方法:

图片

从这个表格可以看出:

  • 首先是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被杀的几率。

来源:https://www.cnblogs.com/xtf2009/p/17947545

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/598546.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习软考----数据库系统工程师22

关系运算 基本的关系代数运算 拓展的关系运算 除:需要S连接中属性为C和D的两个元组都与R连接一样,且在R连接中对应的另外的元素完全一致 总结

VBA在Excel中注册登录界面的应用

Excel工作表也可以做一个小程序,登录注册后可以访问或修改。为了简便,没有做复杂的控件,能说明问题就行。可以根据需要添加更多的判断条件,控制注册和访问人数。本次操作对注册没有任何限制,只要注册后就可以根据注册的账号和密码进行访问和修改。注册登录界面截图: 操作…

【数据结构】 顺序表专题

目录 1.顺序表的概念及结构 1.1线性表 1.2顺序表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 1.顺序表的概念及结构 1.1线性表 线性表(Linear List)是数据结构中的一种基本结构,它是一个具有n个数据元素的有限序列。线性表的特点是数…

速卖通新卖家测评攻略:从入门到精通

在电商行业中,测评被广泛认为是提升产品转化率和销量的有效手段。对于速卖通的卖家而言,测评的必要性更是显而易见。测评,本质上与国内电商的补单行为相似,是一种通过增加销量来提升产品权重的方法。 特别是在竞争激烈的类目中&a…

Colibri for Mac v2.2.0 原生无损音频播放器 激活版

Colibri支持所有流行的无损和有损音频格式的完美清晰的比特完美播放,仅使用微小的计算能力,并提供干净和直观的用户体验。 Colibri在播放音乐时使用极少的计算能力。该应用程序使用最先进的Swift 3编程语言构建,BASS音频引擎作为机器代码捆绑…

VS code ESP-IDF 提示“loading ‘build.ninja‘: 系统找不到指定的文件” 的解决方案

最近在搞esp32,使用VS code进行开发,但是当把别人的工程直接导进去的时候编译报错找不到文件: 但是在之前明明已经新建工程成功了,那应该是缺少某些文件吧。在网上找到一种方法就是将文件拷贝到之前新建的文件里面,确…

Wish、Newegg、Allegro卖家如何做测评补单 快速提升产品权重与销量

大部分主流平台卖家都会使用测评补单来增加产品权重、提高销量。经常会有一些平台的卖家咨询我其他平台能否像亚马逊一样通过测评补单来提升曝光。 其实大部分跨境电商都是可以通过补单来增加店铺权重提升产品排名。其实亚马逊相对来说风控是最严的,风控点多达几十…

WouoUIPagePC端实现

WouoUIPagePC端实现 WouoUIPage是一个与硬件平台无关,纯C语言的UI库(目前只能应用于128*64的单色OLED屏幕上,后期会改进,支持更多尺寸)。因此,我们可以在PC上实现它,本文就以在PC上使用 VScode…

网络安全之动态路由RIP详解

RIP:路由信息协议 RIP分为三个版本:RIPV1,RIPV2(在IPv4中使用),RIPNG(在IPv6中使用) RIPV1是一种有类别的距离矢量型路由协议(不传递网络掩码)。 RIPV2是一种无类别的距离矢量型路…

Java代码基础算法练习-删除有序数组中的重复项-2024.05.07

任务描述: 给一个有序数组(共10个元素),请在不新建数组的情况下,删除重复出现的元素,使 每个元素只出现一次,最后请输出删除重复元素后数组的新长度和数组元素。 解决思路: 要删除…

javascript中的DOM和BOM

目录 JavaScript中的对象 简介: js对象的基本用法: 创建对象: 访问对象的属性: 设置修改对象的属性: 删除对象的属性: DOM(文档对象模型) 简介: DOM对象的属性…

【毕业设计】基于微信小程序的校园快递平台系统设计与实现

1.项目介绍 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统校园快递平台系统信息管理难度大,容错率…

性能测试常见风险以及消减措施

性能测试过程中会遇到各种各样的风险,常见风险以及消减措施有哪些? 一: 时间 一)时间相关风险 时间相关风险不仅限于最终用户满意度,尽管这是大多数人首先想到的。时间也是某些与业务和数据相关的风险因素。性能测试可以解决的…

链表+环-链表是否有环的判断

链表是否有环的判断 在数据结构中,链表是一种常见的数据结构,它允许我们在不需要预先知道数据总量的情况下进行数据的动态存储。然而,由于链表的特性,有时我们可能会遇到链表中出现环的情况,即链表的某个节点指向了链…

NXP i.MX8系列平台开发讲解 - 1.1 导读前言

专栏文章目录传送门:返回专栏目录 文章目录 目录 1. 本专辑介绍 2. 学习本专辑作用 3.关于作者 1. 本专辑介绍 本专辑将会介绍Linux 驱动开发,Android BSP 驱动涉及HAL层调试,适用于嵌入式软件开发人员,和有兴趣向该方向发展…

怎么制作地图位置二维码?扫码获取地图信息的方法

随着互联网的不断发展,二维码在工作和生活中的应用不断的增多,可以针对不同的用途展示内容。比如现在很多的商家或者店铺会将定位定制生成二维码,印刷到传单或者宣传海报上,就可以让用户通过扫码获取位置,方便精准定位…

(论文阅读-分析引擎)Modin

一、简介 目标是在不改变的Dataframe语义的情况下支持可扩展的dataframe操作。 什么是机会主义评价?Opportunistic Evaluation? Exploratory data analysis(EDA):总结、理解并从数据集中获取价值的过程。 MPI&#…

如何使用dockerfile文件将项目打包成镜像

要根据Dockerfile文件来打包一个Docker镜像,你需要遵循以下步骤。这里假设你已经安装了Docker环境。 1. 准备Dockerfile 确保你的Dockerfile文件已经准备就绪,并且位于你希望构建上下文的目录中。Dockerfile是一个文本文件,包含了用户可以调…

Omnity 进展月报 | 2024.4.1-4.30

Omnity 大事摘要 1、Octopus 官宣升级为 Omnity。 2、Omnity 4月28号正式上线,实现BTC 和 ICP 之间跨链转账 Runes 资产。 3、为庆祝上线,以符文 HOPE•YOU•GET•RICH 为资产,发红包快速触达大量用户,体验跨链服务。 4、Omni…

layui的treeTable组件,多层级上传按钮失效的问题解决

现象描述: layui的treeTable 的上传按钮在一层能用,展开后其他按钮正常点击,上传按钮无效。 具体原因没有深究,大概率是展开的子菜单没有被渲染treeTable的done管理到,导致没有重绘上传按钮。 解决方案: 不使用layu的上传组件方法…