08 | 容器内存:我的容器为什么被杀了?
该思维导图由 AI 生成,仅供参考
问题再现
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了容器内存管理中的重要问题:当容器中的进程使用了过多的内存时,Linux系统会主动杀死一个进程来释放内存,导致整个容器退出。文章通过模拟容器被杀死的场景,解释了OOM Killer的概念和工作原理。OOM Killer是Linux系统中的一个机制,当内存不足时,会选择杀死正在运行的进程来释放内存。文章还介绍了Linux进程的内存申请策略和OOM Killer选择进程的标准。通过这些内容,读者可以了解容器内存管理中的重要概念和机制,以及OOM Killer的工作原理,有助于他们更好地理解和解决容器内存管理中的问题。 文章还详细介绍了Memory Cgroup的运行机制,包括memory.limit_in_bytes、memory.oom_control和memory.usage_in_bytes等参数的作用。通过这些参数,读者可以了解如何限制一组进程的内存使用量,并且了解OOM Killer的触发条件和处理方式。此外,文章还提供了解决OOM问题的方法,包括如何通过内核日志及时发现OOM事件,并对消耗最多内存的进程进行分析和处理。 总的来说,本文通过深入讲解OOM Killer和Memory Cgroup的概念,帮助读者理解了容器内存管理中的关键问题,并提供了解决OOM问题的思路和方法。这对于从事容器管理和系统运维工作的读者来说,是一篇具有实际应用意义的技术文章。
《容器实战高手课》,新⼈⾸单¥59
全部留言(29)
- 最新
- 精选
- Bill Du老师请教下 k8s中limit 是 改的 limit in bytes。那k8s request是改的mem cg中哪个指呀?
作者回复: k8s request不修改Memory Cgroup里的参数。只是在kube scheduler里调度的时候看做个计算,看节点上是否还有内存给这个新的container。
2020-12-03325 - 谢哈哈如果将memory oom control的参数设置为1,那么容器里的进程在使用内存到达memory limit in bytes之后,不会被oom killer杀死,但memalloc进程会被暂停申请内存,状态会变成因等待资源申请而变成task interruptable
作者回复: @谢哈好, > 但memalloc进程会被暂停申请内存,状态会变成因等待资源申请而变成task interruptable 挺好的,能分析最后进程的状态。
2020-12-02322 - 垂死挣扎的咸鱼请问老师:这边提到的cgroup底下的memory.usage_in_bytes是不是可以理解为通过top看到的usage与buffer/cached内存之和(这边指在容器中执行top且该容器有绑定lxcfs或者直接是kata容器即理解为top看的就是该容器的),因为我们这边用prometheus采集监控指标的时候发现container_memory_usage_bytes这个指标与cgroup中memory.usage_in_bytes是对应的而container_memory_usage_bytes这个指标实际是算上buffer/cached的内存,同时这边衍生出一个问题假如oom的评判标准是包含buffer/cached的内存使用,那是不是意味着我们在做容器内存监控的时候是应该把这个值也展示在监控中?
作者回复: >这边提到的cgroup底下的memory.usage_in_bytes是不是可以理解为通过top看到的usage与buffer/cached内存之和 是的 > 同时这边衍生出一个问题假如oom的评判标准是包含buffer/cached的内存使用 OOM是不包含buf/cache的。总的memory usage如果超过memory limit, 那么应该是先发生memory reclaim去释放cache。
2021-01-23210 - AdamCPU应该是可压缩资源,即便达到设置的资源限额也不会退出,而内存属于不可压缩资源,资源不足时就会发生OOM了。
作者回复: 嗯,可以这么理解
2020-12-049 - wuqilv老师,我在ubuntu上按照文章进行操作,容器没有按照预期那样发生 oom kill,查看 state ,"OOMKilled": false。
作者回复: @wuqilv, 你可以用free看一下,是不是swap打开了?
2020-12-0265 - 垂死挣扎的咸鱼老师这边请教一个问题,今天排查oom的日志时发现 agent invoked oom-killer: gfp_mask=0x6000c0(GFP_KERNEL), nodemask=(null), order=0, oom_score_adj=-998 ...... Killed process 3267 (agent) total-vm:4912320kB, anon-rss: 2074576kB, file-rss: 23000kB, shmem-rss:0kB 这么一段,其中对容器limit限制是2GIB,因此猜测为oom触发条件是 anon-rss + file-rss > limit时触发,然后看到您在评论里有描述过条件是: 新申请的内存+ memory.usage_in_bytes - reclaim memory > memory.limit_in_bytes 所以这边对这个新申请内存有些疑惑,这边有两种猜测: (1)这边的新申请内存指的是虚拟内存吗,如果是的话是不是意味着oomkill流程触发是在程序申请内存的时候,但是这边看之前oom日志中vm的内存已经远超limit了 (2) 这边猜测这边的新申请内存是实际的物理内存这样,按照这种猜测oomkill流程是在程序实际使用时触发该流程,如果这种猜测是准的话,想请问一下是否anon-rss + file-rss 就等于新申请的内存+ memory.usage_in_bytes - reclaim memory 这样 这边确实对oom这一块十分困惑,网上找到的资料也千奇百怪,内核代码不知道该怎么入手看这一块,所以想请教一下老师这些问题,麻烦老师了
作者回复: @垂死挣扎的咸鱼 > (1) 新申请的内存还是指物理内存。虚拟内存是不会引起OOM的。 > 想请问一下是否anon-rss + file-rss 就等于新申请的内存+ memory.usage_in_bytes - reclaim memory 其实这里最大的一点就是内核的内存是否被计入到cgroup memory中。缺省情况内核使用的内存会被计入到cgroup里, 不过对于大部分运行应用程序的容器里, anon-rss + file-rss就是最主要的物理内存开销(这里不包含内核内存)。 但是如果一个容器中的进程对应的内核内存使用量很大那么我觉得更加准确的就是看 “新申请的内存+ memory.usage_in_bytes - reclaim memory” 了。
2021-02-2523 - Lemon老师,请问控制组之间是什么关系呢? 按照本章的树状的层级结构图所示,group1 分出 group2 和 group3 。 此时 group1 里的 memory.limit_in_bytes 设置的值是 200MB,这里的 200MB 是代表是的什么呢? 是指 group2 + group3 + group1 的所有进程使用的内存总值就不能超过 200MB? 还是单纯的指 group2 与 group3 中各自的所有进程使用的内存总值就不能超过 200MB?
作者回复: 是第一种情况: > 是指 group2 + group3 + group1 的所有进程使用的内存总值就不能超过 200MB?
2021-01-293 - 维c参照着网络上的解析和内核的代码看了一下整个oom回收的flow,发现oom_killer_disabled这个标志位在out_of_memory 函数的一开始就做了检测,那么这个标志位由什么决定的呢?如果容器内的进程也可以设置这个标志位,是不是就等于禁止掉了回收机制而导致容器内进程内存管理的失控呢?
作者回复: 在memory cgroup中可以通过memory.oom_control来禁止对应cgroup中的oom killer。 禁止oom killer不会导致内存管理失控,它也不是内存的回收机制。
2020-12-232 - Geek_ba556dk8s的memory的request,limit限制对应cgroup的参数是什么?
作者回复: limit 对应 Memory Cgroup中的memory.limit_in_bytes k8s request不修改Memory Cgroup里的参数。只是在kube scheduler里调度的时候看做个计算,看节点上是否还有内存给这个新的container。
2020-12-0322 - Acter请问老师:进程的cache和buffer也会计入进程已使用的物理内存页面数吗?
作者回复: @Acter,好问题,下一课,我会讲这个问题
2020-12-022