创建 memory cgroup 失败原因与解决方案

现象

测试环境中一台机器上的pod转移到其他节点,涉及大量的容器创建和销毁。偶尔会遇到 memory cgroup 无法创建的问题。体现在日志上如下:

Dec 22 08:00:00  kubelet: E1222 08:00:00.498519   15276 pod_workers.go:190] Error syncing pod 568af631-f663-4475-86f2-fa6bf1612659 ("crawler-api-7948c5bc95-5kgp8_brown(568af631-f663-4475-86f2-fa6bf1612659)"), skipping: failed to ensure that the pod: 568af631-f663-4475-86f2-fa6bf1612659 cgroups exist and are correctly applied: failed to create container for [kubepods besteffort pod568af631-f663-4475-86f2-fa6bf1612659] : mkdir /sys/fs/cgroup/memory/kubepods/besteffort/pod568af631-f663-4475-86f2-fa6bf1612659: cannot allocate memory
Dec 22 08:00:01  dockerd: time="2020-12-22T08:00:01.237276548+08:00" level=error msg="Handler for POST /containers/394d2d6299fa46be7056e82ac9504fd1488b0af87fdadbe9b907d882eb7b3b8f/start returned error: OCI runtime create failed: container_linux.go:349: starting container process caused \"process_linux.go:297: applying cgroup configuration for process caused \\\"mkdir /sys/fs/cgroup/memory/kubepods/besteffort/pod2d78b9c8-6696-46ac-8326-aa9477f1b1d0/394d2d6299fa46be7056e82ac9504fd1488b0af87fdadbe9b907d882eb7b3b8f: cannot allocate memory\\\"\": unknown"

手动创建时,错误如下:

mkdir: cannot create directory '/sys/fs/cgroup/memory/test': Cannot allocate memory
原因

3.10.x 内核的 memory cgroup 实现中 kmem accounting 相关是 alpha 特性,实现上由许多 BUG 。具体我们的场景,开启 kmem accouting 后有两个问题:

SLAB 泄露,具体可以参见 Try to Fix Two Linux Kernel Bugs While Testing TiDB Operator in K8s | TiDB
memory cgroup 泄露,删除后不会被完全回收。又因为内核对 memory cgroup 总数有 65535 总数限制,频繁创建删除开启了 kmem 的 cgroup ,会让内核无法再创建新的 memory cgroup ,出现上面的错误。
问题复现与修复验证脚本
“SLAB” 泄露
可以观察 k8s pods 创建过程中,系统 slab 情况。若稳定增长,则存在泄露。

watch -n 1 'ls /sys/kernel/slab  | wc -l'

当然也可以手动创建 cgroup 并开启 kmem 后删除来模拟。

此问题,在 CentOS 7.6 的当前最新内核 (3.10.0-1062.12.1.el7.x86_64) 中已修复。

Memory Cgroup 泄露
先将所有的 memory cgroup 耗尽:

mkdir /sys/fs/cgroup/memory/test
for i in `seq 1 65535`;do mkdir /sys/fs/cgroup/memory/test/test-${i}; done

在其中一个 cgroup 中打开 kmem ,然后删除:

for n in 1 -1; do
echo $n > /sys/fs/cgroup/memory/test/test-1/memory.kmem.limit_in_bytes
done
echo $$ > /sys/fs/cgroup/memory/test/test-1/cgroup.procs
echo $$ > /sys/fs/cgroup/memory/cgroup.procs
rmdir /sys/fs/cgroup/memory/test/test-1

尝试重新创建:

mkdir /sys/fs/cgroup/memory/test/test-1

此问题,在 CentOS 7.6 的当前最新内核 (3.10.0-1062.12.1.el7.x86_64) 中还未修复,需要开使用 “cgroup.memory=nokmem” 内核参数全局禁用 kmem 来避免。

总结

若系统发行版本无法升级,可以通过以下方案解决:

方法一
业务层不使用 kmem 特性,比如 kubelet 需要使用 nokmem BUILDTAG 来编译,具体可以参见 https://pingcap.com/blog/try-to-fix-two-linux-kernel-bugs-while-testing-tidb-operator-in 。

方法二
但不是所有的场景都方便关闭 kmem 使用。比如容器中创建 k8s 集群测试。此时,可以在内核层全局使用 “cgroup.memory=nokmem” 参数关闭。

注意,内核需要升级到 CentOS 7.6 的最新版(当前为: 3.10.0-1062.12.1.el7.x86_64) ,以修复 SLAB 泄露问题。

若系统发行版可以升级,建议直接升级到 CentOS 8 。内核为 4.x 版本,cgroup 相关实现各方面都健壮许多。

从 RedHat 的 Issue 中,据说问题在 7.8 的 kernel-3.10.0-1075.el7 最终修复了。等 CentOS 7.8 发布后,也是一个选择。

参考文章

https://zhuanlan.zhihu.com/p/106757502
https://help.mulesoft.com/s/article/RTF-How-to-Resolve-the-Cgroup-Memory-Leaking-Issue-in-Runtime-Fabric

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: "memory cgroup out of memory" 的意思是内存控制组(memory cgroup)已经用尽了内存。这通常是由于系统中运行的进程使用了过多的内存,导致内存不足。需要释放一些内存或增加系统内存才能解决这个问题。 ### 回答2: memory cgroup out of memory的意思是,内存控制组(memory cgroup)已经耗尽了内存。内存控制组是Linux内核提供的一种资源管理机制,可用于对进程或进程组进行资源限制。这些资源包括内存、CPU和IO等。内存控制组指定了一个可用的内存限额,一旦进程或进程组使用的内存超过了这个限额,就会出现内存不足的情况。 当出现memory cgroup out of memory错误时,它通常是由以下几个原因造成的: 1. 系统内存资源已经很紧张,没有足够的空闲内存可供使用。 2. 特定进程或进程组尝试使用超出其内存限额的内存。 3. 内存控制组的配置不正确,导致内存限额设置不合理,或者内存控制组的hierarchy(内存层次结构)可能过于复杂,导致某些进程无法正确地使用内存。 为解决这个问题,您可以尝试以下几种方法: 1. 扩大系统内存,增加可用内存资源。 2. 查找和解决内存泄漏问题,或是降低进程的内存消耗。 3. 重新配置内存控制组,调整内存限额等。 总之,内存不足是一个常见的系统问题,需要我们根据具体情况迅速找到并解决问题,以保证系统的正常运行。 ### 回答3: Memory cgroup out of memory是一个操作系统中的错误信息,它表示系统不能满足当前进程运行所需的内存,通常出现在Linux系统中。这个错误的原因是内存限制控制组(memory cgroup)已经超出了其允许的内存资源,导致当前的进程无法获取所需的内存,从而无法正常运行。 内存限制控制组是Linux系统提供的一种机制,用于限制进程的内存使用。每个进程都可以被分配到不同的内存限制控制组中,并且每个控制组都可以定义该组中进程所允许的最大内存使用量。当一个进程尝试超过其控制组允许的最大内存使用量时,就会出现Memory cgroup out of memory错误。 这种错误的出现可能是因为系统内存不足,也可能是因为某些进程占用了过多的内存资源。解决这个问题的方法有很多,其中一种方法是通过增加系统内存来缓解问题。另外,也可以尝试通过调整内存限制控制组的配置,来优化系统的内存使用。同时,优化进程运行中的内存使用也是解决这个问题的关键。例如,可以减少进程的内存使用,或者通过实现内存复用等技术来优化内存的使用效率。 总之,Memory cgroup out of memory是系统资源管理中常见的错误,需要针对具体情况进行分析和优化,以保证系统的稳定性和可靠性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值