前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >K8S内存消耗,到底该看哪个图?

K8S内存消耗,到底该看哪个图?

原创
作者头像
HelloMin
发布于 2022-05-30 03:10:26
发布于 2022-05-30 03:10:26
4.7K00
代码可运行
举报
文章被收录于专栏:Pair ProgrammingPair Programming
运行总次数:0
代码可运行

最近的一项工作,是查看服务在过去一段时间的内存实际使用量,给K8S平台上的POD内存设置一个基于历史数据的合理上限,既不会限制服务的正常运行,也可以尽量减少不必要的占坑。

本来是一个很简单的工作,按理说看看图,确定下最高峰的内存消耗,也就结束了。谁知这个看图的过程中看出些奇妙,事后竟花了2天的时间看了十几篇文章来研究,刚给米国的同事写了一封能翻好几页的邮件来讲这个问题,自己也总结一下。

先说奇妙。结合多个线上的监控图,我发现,使用不同的监控指标,看出来的内存使用情况差距很大。

如果用RSS作为指标,内存一直很稳定:

但是用WORKING SET作为指标,我们的内存好像一直在狂涨,而且分分钟要涨到目前的POD上限...

那么问题就来了,我们到底应该看哪个指标,来确定POD内存的使用上限呢?

故事一开始,还得从Linux讲起。Linux支持给不同的进程划分Cgroup,也就是拉小群,一个群里的进程共享本群的资源,包括内存CPU等等,Docker底层就是用了Cgroup来达到容器的资源控制。

划分了Cgroup来给不同的进程做资源隔离之后,Linux本身就提供了很多指标,来展示Cgroup内的内存使用情况,这里我们比较关心的值有:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ cat /sys/fs/cgroup/memory/memory.stat cache xxx rss xxxinactive_file xxxactive_file xxx

上面四个值中:

cache自然指的是缓存,包括文件缓存

rss指的是常驻内存,是分配给进程使用的实际物理内存,包括进程使用的栈内存,堆内存,以及共享库的内存

inactive_file和active_file,按照我的理解都是文件缓存,两者的区别是,一个文件第一次被访问,会算做inactive file, 被访问了两次之后,就会从inactive file的小队,归到active file的小队。

到了K8S这边,为了用户监控POD的内存消耗,K8S层面也暴露了很多不同的内存指标,我们这里比较关心的是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
container_memory_cache -- 缓存占用的大小container_memory_rss -- RSS占用的大小container_memory_usage_bytes -- 当前使用内存,包括所有内存,不管有没有被访问container_memory_working_set_bytes -- 当前内存工作集使用量

从K8S的源码可以看出,K8S的指标,实际上就是对上面Linux的指标做了一些计算之后得出的:

RSS的计算方式很直观,就是读取了total rss:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ret.Memory.RSS = s.MemoryStats.Stats["total_rss"]

WORKING SET的计算方式则是K8S自创的,用的是usage减去inactive file:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inactiveFileKeyName := "total_inactive_file"if cgroups.IsCgroup2UnifiedMode() { inactiveFileKeyName = "inactive_file"}workingSet := ret.Memory.Usageif v, ok := s.MemoryStats.Stats[inactiveFileKeyName]; ok {if workingSet < v {  workingSet = 0 } else {  workingSet -= v }}ret.Memory.WorkingSet = workingSet

从上面可以看出,我们关心的两个指标的来源是不同的:RSS只关心进程实际使用的内存,但是WORKING SET还把active file也算进去了,也就是说,文件缓存这部分也算进去了。

那下一个问题就是,K8S OOM的标准到底是什么?按理说,文件缓存既然是缓存,到了危机时刻,内存压力山大的时候,文件缓存都该让位给进程,这部分缓存应该都是可以写回磁盘,腾出地方来给进程使用的。

但是实际情况是,当缓存占用的空间巨大时,K8S会认为内存达到上限直接杀掉POD重新调度。这个问题在Github上提了个Issue,总有人发现自己POD的RSS很低,Cache很大的时候,也被K8S杀掉了:

这个Issue从2017年被人发现,直到四天前还有人在回,可见也是一个老毛病了...但至少可以得出结论,缓存所占的内存也是会导致OOM的。

在浏览了各种Issue之后我发现,K8S考虑缓存也许不是没有理由的。在另一个Issue中,有人也遇到类似的坑,最后发现,不是所有的底层文件系统都能支持Dirty文件缓存写回的。那要是要的时候缓存不肯让座儿,进程本身又要更多内存,那可不就,全玩儿完...

综上,虽然文件缓存确实应该不算在进程使用的内存中,但是在K8S上,很显然它的存在对于POD的生死是有决定性的影响的。综上,我认为监测WORKING SET是更符合实际情况的,我们这里的内存上涨也是需要被关注的。

就是这样。

疫情期间上班抢菜已经费尽所有脑力,但还是想好好搞清楚一个问题,也许这就是死理性派的小执着吧...

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
K8S内存消耗,到底该看哪个图?
最近的一项工作,是查看服务在过去一段时间的内存实际使用量,给K8S平台上的POD内存设置一个基于历史数据的合理上限,既不会限制服务的正常运行,也可以尽量减少不必要的占坑。
HelloMin
2022/08/11
5.7K2
K8S内存消耗,到底该看哪个图?
Linux 进程内存监控:Linux 内存调优之进程内存深度监控
这里分析的工具主要是原生工具,后面还会分享一些 BPF 相关的内存观察工具以及系统内存的全局监控
山河已无恙
2025/04/13
3080
Linux 进程内存监控:Linux 内存调优之进程内存深度监控
聊聊docker容器的memory限制
所谓Cache,就是为了弥补高速设备和低速设备之间的矛盾而设立的一个中间层。 缓冲(Buffer)是根据磁盘的读写设计的,它把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。
code4it
2024/04/12
2070
聊聊docker容器的memory限制
聊聊docker容器的memory限制
所谓Cache,就是为了弥补高速设备和低速设备之间的矛盾而设立的一个中间层。 缓冲(Buffer)是根据磁盘的读写设计的,它把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。
code4it
2024/04/08
4350
kubectl top 命令解析
kubectl top 可以很方便地查看node、pod 的实时资源使用情况:如CPU、内存。这篇文章会介绍其数据链路和实现原理,同时借 kubectl top 阐述 k8s 中的监控体系,窥一斑而知全豹。最后会解释常见的一些问题:
我是阳明
2020/06/15
31.6K0
kubectl top 命令解析
揭开K8s适配CgroupV2内存虚高的迷局
在Almalinux替换CentOS的过程中,我们通过kubectl top nodes命令观察到了两个相同规格的节点(只有cgroup版本不同)。在分别调度两个相同的Pod后,我们预期它们的内存使用量应该相近。然而,我们发现使用了cgroupv2的节点的内存使用量比使用了cgroupv1的节点多了约280Mi。
zouyee
2023/11/15
7350
揭开K8s适配CgroupV2内存虚高的迷局
从RSS到WSS:深入Kubernetes内存指标
无论您是 DevOps 工程师、系统管理员还是刚入门 Kubernetes 的人,了解内存指标可能会改变游戏规则。
云云众生s
2024/03/28
2.7K3
从RSS到WSS:深入Kubernetes内存指标
动图理清 K8S OOM 和 CPU 节流
使用 Kubernetes 时,内存不足 (OOM) 错误和 CPU 节流是云应用程序中资源处理的主要难题。
我的小碗汤
2023/03/20
1.4K0
动图理清 K8S OOM 和 CPU 节流
动态清理 K8S OOM 和 CPU 节流
使用 Kubernetes 时,内存不足 (OOM) 错误和 CPU 节流是云应用程序中资源处理的主要难题。
iginkgo18
2023/05/22
1.2K0
K8S 问题排查:cgroup 内存泄露问题
这篇文章的全称应该叫:[在某些内核版本上,cgroup 的 kmem account 特性有内存泄露问题],如果你遇到过 pod 的 cannot allocated memory 报错,node 内核日志的 SLUB: Unable to allocate memory on node -1 报错,那么恭喜你中招了。
YP小站
2020/11/03
9.3K0
K8S 问题排查:cgroup 内存泄露问题
centos7 cgroup oom触发访问ext4文件系统卡死
centos7 3.10.0-1160.62.1.el7.x86_64内核版本已修复该问题,CentOS7受影响内核版本 3.10.0-862.el7 - 3.10.0-1160.59.1.el7
cdh
2022/04/15
2.8K3
软件测试 | Chrome 浏览器+Postman还能这样做接口测试 ?
如果把测试简单分为两类,那么就是客户端测试和服务端测试。客户端的测试包括UI测试,兼容性测试等,服务端测试包括接口测试。接口测试检查数据的交换,传递和控制管理过程,它绕过了客户端,直接对服务端进行测试。
霍格沃兹测试开发
2021/07/14
1.1K0
K8s监控之Metrics-Server指标获取链路分析
Metrics-server基于cAdvisor收集指标数据,获取、格式化后以metrics API的形式从apiserver对外暴露,核心作用是为kubectl top以及HPA等组件提供决策指标支持。
壹贝
2022/11/30
4.1K1
Kubernetes 内存资源限制实战
Kubernetes 对内存资源的限制实际上是通过 cgroup 来控制的,cgroup 是容器的一组用来控制内核如何运行进程的相关属性集合。针对内存、CPU 和各种设备都有对应的 cgroup。cgroup 是具有层级的,这意味着每个 cgroup 拥有一个它可以继承属性的父亲,往上一直直到系统启动时创建的 root cgroup。关于其背后的原理可以参考:深入理解Kubernetes资源限制:内存。
米开朗基杨
2019/08/29
3.1K0
Kubernetes 内存资源限制实战
SpringBoot 接口快速开发神器(接口可视化界面实现)
magic-api 是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对象即可完成常见的HTTP API接口开发
java思维导图
2021/12/06
5520
Kubernetes 中 Evicted pod 是如何产生的
最近在线上发现很多实例处于 Evicted 状态,通过 pod yaml 可以看到实例是因为节点资源不足被驱逐,但是这些实例并没有被自动清理,平台的大部分用户在操作时看到服务下面出现 Evicted 实例时会以为服务有问题或者平台有问题的错觉,影响了用户的体验。而这部分 Evicted 状态的 Pod 在底层关联的容器其实已经被销毁了,对用户的服务也不会产生什么影响,也就是说只有一个 Pod 空壳在 k8s 中保存着,但需要人为手动清理。本文会分析为什么为产生 Evicted 实例、为什么 Evicted 实例没有被自动清理以及如何进行自动清理。
米开朗基杨
2021/10/18
1K0
Kubernetes 中 Evicted pod 是如何产生的
kubernetes 中 Evicted pod 是如何产生的
最近在线上发现很多实例处于 Evicted 状态,通过 pod yaml 可以看到实例是因为节点资源不足被驱逐,但是这些实例并没有被自动清理,平台的大部分用户在操作时看到服务下面出现 Evicted 实例时会以为服务有问题或者平台有问题的错觉,影响了用户的体验。而这部分 Evicted 状态的 Pod 在底层关联的容器其实已经被销毁了,对用户的服务也不会产生什么影响,也就是说只有一个 Pod 空壳在 k8s 中保存着,但需要人为手动清理。本文会分析为什么为产生 Evicted 实例、为什么 Evicted 实例没有被自动清理以及如何进行自动清理。
田飞雨
2021/10/08
5.5K0
图解K8s源码 - kubelet 下的 QoS 控制机制及 k8s Cgroups v2 简介
在日常使用 K8s 时,难免遇到 Node 上资源紧张导致节点中的 Pod 被 OOMKill 掉的情况,哪些 Pod 会被 kill 呢?又是根据什么评判标准来确定的优先级呢?
才浅Coding攻略
2023/03/01
1.6K0
图解K8s源码 - kubelet 下的 QoS 控制机制及 k8s Cgroups v2  简介
4.11|今天的开发者头条,都搁这了!
Chrome浏览器现已默认支持WebGPU技术,可直接使用。WebGPU是一种新的Web图形API,它可以提供更灵活的GPU编程,同时还能访问WebGL无法提供的高级功能。它公开了现代硬件功能,允许在GPU上进行渲染和计算操作。WebGPU显著减轻了JavaScript的工作负担,同时在机器学习模型推理方面提供了超过三倍的性能提升。目前,WebGPU仅适用于ChromeOS、macOS和Windows。其他平台的WebGPU支持将在今年晚些时候推出。
漫话开发者
2023/04/11
7961
4.11|今天的开发者头条,都搁这了!
Linux中进程内存与cgroup内存的统计
在Linux内核,对于进程的内存使用与Cgroup的内存使用统计有一些相同和不同的地方。
用户9732312
2022/05/13
2.7K0
推荐阅读
相关推荐
K8S内存消耗,到底该看哪个图?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验