重学容器31: 容器资源限制之限制容器的内存
文章目录
【注意】最后更新于 July 30, 2021,文中内容可能已过时,请谨慎使用。
linux memory cgroup子系统
限制容器的内存使用需要借助memory cgroup子系统。
在使用cgroups时需要先挂载,例如在centos下memory cgroup子系统被挂载到了/sys/fs/cgroup/memory
下,,在这个目录下是各个memory控制组目录,每个控制组目录下还可以有子目录,各个控制组形成了一个树状的层级关系。
例如在/sys/fs/cgroup/memory
下创建一个名为foo的pids控制组目录,控制组目录中有如下内容:
|
|
task
文件中是控制组中的进程id,可以把某个进程添加到这个控制组中,另外memory.usage_in_bytes
是只读的,它的值是当前控制组中所有进程使用的内存总和。
重点关注memory.limit_in_bytes
, memory.oom_control
文件的值:
memory.limit_in_bytes
: 用来设置控制组中所有进程可以使用内存的最大值
memory.oom_control
用来设置当控制组中所有进程达到可以使用内存的最大值时,也就是发生OOM(Out of Memory)时是否触发linux的OOM killer杀死控制组内的进程。默认的配置是开启OOM killer的。
|
|
下面演示如何删除上面创建的控制组foo目录,可以使用libcgroup-tools
工具:
|
|
限制containerd容器内存
nerdctl run
启动一个containerd容器时,可以使用-m
选项指定容器的最大内存
|
|
下面使用nerdctl启动一个containerd容器,限制其内存使用为100Mb,并在服务器上查找一下它的memory cgroup目录。
|
|
可以在/sys/fs/cgroup/memory/default
目录下下出现了一个与容器ID同名的目录,目录中的memory.limit_in_bytes
文件的值为104857600 bytes
即100Mb:
|
|
注意/sys/fs/cgroup/memory
中default
目录是containerd中的namespace概念,默认是default,如果启动容器时指定了namespace,则就是对应的namespace目录。如nerdctl -n mynamespace run -m 100m -d redis:alpine3.14
,则控制组就在/sys/fs/cgroup/memory/mynamespace
目录的以容器id为名称的子目录里。
k8s如何使用memory cgroup限制容器cpu
最后根据结合Kubernetes中对容器的资源限制requests.memory
和limits.memory
,到k8s容器的memory控制组目录中看一下是如何设置的。
这个k8s集群的版本是1.21,容器运行时使用的是containerd。
在这个集群中部署了Kubernetes的Dashboard,设置了dashboard容器的资源限制情况如下:
|
|
即limits.memory为200Mi,requests.memory为200Mi。memory控制组目录的具体位置可以参考前面第29节中查找cpu控制组目录的方法,这里略过:
|
|
可以看到k8s里pod容器的requests.memory
不会修改memory cgroup里的memory.limit_in_bytes
,只是在k8s调度时用来计算使用的,看某个k8s节点上是否有可用内存分配给这个pod的容器。而k8s里pod容器的limits.memory
被设置到memory cgroup里的memory.limit_in_bytes
。
文章作者 青蛙小白
上次更新 2021-07-30