k8s故障排查个案:当Pod内存持续增长,OOM问题如何解决?

news/发布时间2024/5/14 6:34:07

pod 运行一段时间后,内存持续增长,甚至 oom 的情况.

动机

容器化过程中,我们经常会发现 kubernetes 集群内 pod 的内存使用率会不停持续增长,加多少内存吃多少内存,如果对 cgroup 内存的构成不是很清楚的情况下,单纯看监控看不出什么问题。

经过一番查阅,目前总结出大致有 2 种导致这种情况的场景。

  1. 内存泄露

  2. io 缓存

案例分析

我们先从内存泄露分析,刚好手头有个 pod 也是这种情况。

内存泄露

进入对应的 pod 内部。我们先看看它用了多少内存,prometheus 也是取这个值做为容器的内存使用率的

# cat /sys/fs/cgroup/memory/memory.usage_in_bytes4192538624
# bytes转GB,结果是 3.9GB

我们查看 grafana ,内存使用率的采集结果与 cgroup 里面的记录一致。

/kubernetes%E6%8E%92%E9%94%99-pod-oom-%E5%86%85%E5%AD%98%E6%8C%81%E7%BB%AD%E5%A2%9E%E9%95%BF/pod%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E7%8E%87%E7%9B%91%E6%8E%A7.png

pod内存使用率监控

我们拉长一下记录看看。

/kubernetes%E6%8E%92%E9%94%99-pod-oom-%E5%86%85%E5%AD%98%E6%8C%81%E7%BB%AD%E5%A2%9E%E9%95%BF/pod%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E7%8E%87%E7%9B%91%E6%8E%A7%E6%8B%89%E9%95%BF.png

pod内存使用率监控拉长

很明显就是发生内存泄露了 ,接下来,我们看看 pod 容器内内存记录。

# cat /sys/fs/cgroup/memory/memory.statcache 36900864
rss 4205309952
rss_huge 2837446656
shmem 0
mapped_file 1351680
dirty 1081344
writeback 0
swap 0
workingset_refault_anon 0
workingset_refault_file 20815872
workingset_activate_anon 0
workingset_activate_file 12029952
workingset_restore_anon 0
workingset_restore_file 8785920
workingset_nodereclaim 0
pgpgin 5688606
pgpgout 5778093
pgfault 2878062
pgmajfault 0
inactive_anon 4224827392
active_anon 0
inactive_file 9543680
active_file 25153536
unevictable 0
hierarchical_memory_limit 4294967296
hierarchical_memsw_limit 4294967296
total_cache 36900864
total_rss 4205309952
total_rss_huge 2837446656
total_shmem 0
total_mapped_file 1351680
total_dirty 1081344
total_writeback 0
total_swap 0
total_workingset_refault_anon 0
total_workingset_refault_file 20815872
total_workingset_activate_anon 0
total_workingset_activate_file 12029952
total_workingset_restore_anon 0
total_workingset_restore_file 8785920
total_workingset_nodereclaim 0
total_pgpgin 5688606
total_pgpgout 5778093
total_pgfault 2878062
total_pgmajfault 0
total_inactive_anon 4224827392
total_active_anon 0
total_inactive_file 9543680
total_active_file 25153536
total_unevictable 0

上面获取内存记录,我们主要关心:

total_cachetotal_rsstotal_inactive_anontotal_active_anontotal_inactive_filetotal_active_file

分别代表的意思:

  • total_cache:表示当前pod缓存内存量

  • total_rss:表示当前应用进程实际使用内存量

  • total_inactive_anon:表示匿名不活跃内存使用量

  • total_active_anon:表示匿名活跃内存使用量,jvm堆内存使用量会被计算在此处

  • total_inactive_file:表示不活跃文件内存使用量

  • total_active_file:表示活跃文件内存使用量

rss 确实是使用了 3.9GB 的量,确实是 pod 容器的真实使用,那么基本就验证了要么程序确实内存不够,要么就是内存泄露了。

io 缓存

除了上面那种内存泄露的场景外,还有一种是 io 缓存导致的内存虚高。如下,wss 比 rss 高出不少,这还不算极端的,只是拿出这个举个例子。

/kubernetes%E6%8E%92%E9%94%99-pod-oom-%E5%86%85%E5%AD%98%E6%8C%81%E7%BB%AD%E5%A2%9E%E9%95%BF/pod%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E7%8E%87%E7%9B%91%E6%8E%A7io.png

pod内存使用率监控

然后,我们来看下容器内存指标的组成结构。

  • container_memory_working_set_bytes

  • container_memory_rss

容器当前使用内存量: container_memory_usage_bytes = total_cache + total_rss

容器当前使用缓存内存: total_cache = total_inactive_file + total_active_file

container_memory_working_set_bytes:container_memory_working_set_bytes = container_memory_usage_bytes - total_inactive_file

带入上面两个公式,容器的工作集的等式可以拆解为:

container_memory_working_set_bytes
= container_memory_usage_bytes - total_inactive_file
= total_cache + total_rss - total_inactive_file
= total_inactive_file + total_active_file + total_rss - total_inactive_file
= total_active_file + total_rss
  • total_rss 为应用真实使用内存量,正常情况下该指标数值稳定,那为何该指标会持续上升而且一直维持很高呢?其实问题就出现在 total_active_file 上。

  • Linux 系统为了提高文件读取速率,会划分出来一部分缓存内存,即 cache 内存,这部分内存有个特点,当应用需要进行 io 操作时,会向 Linux 申请一部分内存,这部分内存归属于操作系统,当应用io操作完毕后,操作系统不会立即回收,当操作系统认为系统剩余内存不足时,才会主动回收这部分内存。

  • container_memory_working_set_bytes 指标升高一部分是应用本身内存使用量增加,另一部分就是进行了 io 操作,total_active_file 升高,该指标异常一般都是应用进行了io相关操作。

总结

知道这些情况后,然后就是解决方法:

  1. 如果是频繁写日志到磁盘或输出日志到标准输出的场景,可以紧张日志输出到标准输出,日志落盘做轮转,比如 50-100MB 一个文件做切割,保留最近几个日志文件即可。昨晚这些后,container_memory_working_set_bytes 的使用率会肉眼可见的回落。

  2. 如果是内存计算比较频繁的服务,可以现在程序的可用内存,比如 jvm ,10G 的 pod 内存,限制程序使用 8.5GB 的的内存,现在对外内存最大使用值 1.5GB,这样就可以预留足够的内存防止 pod oom 了。只是打个比方,具体还得根据真实场景所需设置。

  3. wss的值:container_memory_working_set_bytes = total_active_file + total_rss

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

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

HarmonyOS-UIAbility组件间交互(设备内)

UIAbility组件间交互(设备内) UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时,会涉及到启动特定的UIAbility,该UIAbility可以是应用内的其他UIAbility,也可以是其他应用的UIAbility(例如启…

HarmonyOS—使用预览器查看应用/服务效果

DevEco Studio为开发者提供了UI界面预览功能,可以查看应用/服务的UI界面效果,方便开发者随时调整界面UI布局。预览器支持布局代码的实时预览,只需要将开发的源代码进行保存,就可以通过预览器实时查看应用/服务运行效果&#xff0c…

visual studio2022使用tensorRT配置

只记录tensorRT在vs中使用时的配置,下载和安装的 文章主页自己寻找。 下载好TensorRT和对应的cuda之后,把tensorRT的锻炼了和lib文件复制粘贴到cuda对应的文件夹中,以方便调用。 完成之后打开vs新建一个tensorRT的项目,然后开始配…

【Vuforia+Unity】AR06-空间环境识别功能(AreaTargets)

Vuforia原理:把被识别的物体转成图、立体图、柱形图,3D模型、环境模型,然后模型生成Vuforia数据库-导入Unity-参考模型位置开始摆放数字内容,然后参考模型自动隐藏-发布APP-识别生活中实物-数字内容叠加上去! 不论你是否曾有过相关经验,只要跟随本文的步骤,你就可以成功…

五种多目标优化算法(MOCS、MOFA、NSWOA、MOAHA、MOPSO)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 多目标优化算法是用于解决具有多个目标函数的优化问题的一类算法。其求解流程通常包括以下几个步骤: 1. 定义问题:首先需要明确问题的目标函数和约束条件。多目标优化问题通常涉及多个目标函数,这些目标函数可能…

电脑休眠之后唤不醒

现象:午休时间电脑休眠了,醒来之后发现在密码输入界面,但鼠标键盘没反应。按重启键或电源机重新开机,结果开不了机。 原因:1、内存条脏了,导致内存条读取失败 2、休眠的时候硬盘休眠了,导致按…

YOLOv9来咧!

文章目录 论文:主要内容一、提出使用PGI(Programmable Gradient Information,可编程梯度信息)来解决信息瓶颈问题和深度监督机制不适合轻量级神经网络的问题。二、设计了GELAN(Generalized ELAN ,广义ELAN)…

《游戏引擎架构》 -- 学习4

资源及文件系统 文件系统 游戏引擎的文件系统API通常提供以下功能: 搜需路径:是含一串路径的字符串,各路径之间以特殊字符(如冒号或分号)分隔,找文件时就会从这些路径进行搜寻。例如在命令行下执行程序&a…

Kubernetes基础(二十四)-Kubernetes删除控制原理

1 级联和非级联删除 k8s资源默认使用级联删除,当执行了删除一个Deployment的操作时,与其关联的ReplicaSet和Pod也会被删除。日常场景中可以指定删除操作为非级联删除,则之后保留下来的资源被称为孤儿对象。 参考:ReplicaSet是Pod…

25-k8s集群中-RBAC用户角色资源权限

一、RBAC概述 1,k8s集群的交互逻辑(简单了解) 我们通过k8s各组件架构,知道各个组件之间是使用https进行数据加密及交互的,那么同理,我们作为“使用”k8s的各种资源的使用者,也是通过https进行数…

element table数据量太大,造成浏览器崩溃。解决方案

这是渲染出来的数据 其实解决思路大致就是&#xff1a;把后台返回的上万条数据&#xff0c;进行分割&#xff08;前端分页&#xff09;&#xff0c;这样先加载几十条&#xff0c;然后再用懒加载的方式去concat&#xff0c;完美解决 上代码 <template><div class&quo…

【高德地图】Android搭建3D高德地图详细教

&#x1f4d6;Android搭建3D高德地图详细教程 &#x1f4d6;第1章 高德地图介绍✅了解高德地图✅2D地图与3D地图 &#x1f4d6;第2章 搭建3D地图并显示✅第 1 步&#xff1a;创建 Android 项目✅第 2 步&#xff1a;获取高德Key✅第 3 步&#xff1a;下载地图SDK✅第 4 步&…

第一节-docker介绍

这里写自定义目录标题 一、什么是docker二、docker和virtual machine三、docker架构 一、什么是docker docker是一种容器引擎&#xff0c;用于构建、部署、运行应用程序和服务。 docker的每个容器通过沙箱机制相互隔离&#xff0c;互不干扰。 docker容器技术相比传统的虚拟机有…

Java面试——锁

​ 公平锁&#xff1a; 是指多个线程按照申请锁的顺序来获取锁&#xff0c;有点先来后到的意思。在并发环境中&#xff0c;每个线程在获取锁时会先查看此锁维护的队列&#xff0c;如果为空&#xff0c;或者当前线程是等待队列的第一个&#xff0c;就占有锁&#xff0c;否则就会…

python入门

python入门 一、python基础二、标识符、关键字、变量、代码注释、模块三、数据类型的数据四、运算符五、程序流程控制六、容器类型数据1、序列2、列表3、元组4、集合5、字典 七、字符串1、表示字符串2、字符串与数字类型的转换3、字符串格式化4、操作字符串 一、python基础 py…

【力扣白嫖日记】178.分数排名

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 178.分数排名 表&#xff1a;Scores 列名类型idintscoredecimal 在 SQL 中&#xff0c;id 是该表的主键。 …

国家治理的数据赋能及其秩序生产(二)

国家治理的数据赋能及其秩序生产(二) 文章目录 国家治理的数据赋能及其秩序生产(二)前言三、大数据赋能国家治理的权力嬗变(一) 数据平权(1)大数据带来的平等(2)大数据技术带来的信息传播(二) 数据制衡(1)大数据思维驱动了公共权力的扩散(三) 数据监察(1)大数…

数据安全之路:深入了解MySQL的行锁与表锁机制

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 数据安全之路&#xff1a;深入了解MySQL的行锁与表锁机制 前言基础innodb中锁与索引的关系如何避免表锁 前言 在当今数据密集的应用中&#xff0c;数据库锁成为了确保数据一致性和并发操作的关键工具…

React18源码: reconcliler启动过程

Reconcliler启动过程 Reconcliler启动过程实际就是React的启动过程位于react-dom包&#xff0c;衔接reconciler运作流程中的输入步骤.在调用入口函数之前&#xff0c;reactElement(<App/>) 和 DOM对象 div#root 之间没有关联&#xff0c;用图片表示如下&#xff1a; 在启…

matlab 凸轮轮廓设计

1、内容简介 略 46-可以交流、咨询、答疑 2、内容说明 略 4 取标段的分析 取标装置是贴标机的核心部件之一&#xff0c;是影响贴标质量和贴标精度的重要因素&#xff0c;取标段是通过取标板与标签的相切运动使得涂有胶水的取标板从标签盒中粘取标签纸[4]&#xff0c;理论…
推荐文章