使用cgroup限制内存

有些场景下需要限制下程序的内存,可以用cgroup来实现。
本次操作的系统为 CentOS 6 或 7

准备下环境

yum install -y libcgroup libcgroup-tools 

修改下内核,让程序可以随便申请内存

echo 1 > /proc/sys/vm/overcommit_memory

关闭交换分区

swapoff -a

实验一

1.创建一个cgroup限制

cd /sys/fs/cgroup/memory/
mkdir test
cd test

进入test会看到自动产生了很多文件
2.修改配置,限制内存在100M内

echo $((100*1024*1024)) > memory.limit_in_bytes

3.编译一个程序来测试下,看能否限制在100M内,代码如下

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    int max = -1;
    int mb = 0;
    char *buffer;
    int i;
#define SIZE 500
    unsigned int *p = malloc(1024 * 1024 * SIZE);

    printf("malloc buffer: %p\n", p);

    for (i = 0; i < 1024 * 1024 * (SIZE/sizeof(int)); i++) {
        p[i] = 123;
        if ((i & 0xFFFFF) == 0) {
            printf("%dMB written\n", i >> 18);
            usleep(100000);
        }
    }
    pause();
    return 0;
}

编译一下

gcc oom.c

使用cgroup来测试下

[root@localhost ~]# cgexec -g memory:test ./a.out 
malloc buffer: 0x7fdbc67e2010
0MB written
4MB written
8MB written
12MB written
16MB written
20MB written
24MB written
28MB written
32MB written
36MB written
40MB written
44MB written
48MB written
52MB written
56MB written
60MB written
64MB written
68MB written
72MB written
76MB written
80MB written
84MB written
88MB written
92MB written
96MB written
Killed

可以看到要超过100M时,程序被结束掉了。
改成50M再测试下

echo $((50*1024*1024)) > /sys/fs/cgroup/memory/test/memory.limit_in_bytes
[root@localhost ~]# cgexec -g memory:test ./a.out 
malloc buffer: 0x7f7b9fec0010
0MB written
4MB written
8MB written
12MB written
16MB written
20MB written
24MB written
28MB written
32MB written
36MB written
40MB written
44MB written
48MB written
Killed

可以看到要超过50M时,程序被结束掉了。

实验二

使用配置文件来限制
增加内存限制的配置

vim /etc/cgconfig.conf 

添加如下内容

group TestGroup {
    memory {
        memory.limit_in_bytes = "52428800";
        memory.swappiness = 0;
    }
}

这里定义了一个TestGroup组,这个组限制的内存为50M,50*1024*1024。

vim /etc/cgrules.conf 

增加如下配置

*:a.out    memory      TestGroup/

这里简单说明下:

*:a.out 程序名,也就是我们要限制的实例
memory: 要限制的内容,比如这里要限制内存
TestGroup:限制的规则,这里使用的是刚才配置的限制50M的规则

启动服务

service cgconfig start
service cgred start
或
systemctl start cgconfig
systemctl start cgred

至此就配置完成了,跑一下程序,观察下内存的使用情况。

[root@localhost opt]# ./a.out 
malloc buffer: 0x7f42cf62d010
0MB written
4MB written
8MB written
12MB written
16MB written
20MB written
24MB written
28MB written
32MB written
36MB written
40MB written
44MB written
48MB written
Killed

改成限制20M,再测试下。更改/etc/cgconfig.conf配置文件,将内存限制在20M,重启cgconfig服务,看内存使用情况:

[root@localhost opt]# ./a.out 
malloc buffer: 0x7fc5521ca010
0MB written
4MB written
8MB written
12MB written
16MB written
20MB written
Killed

可以看到内存超过20M时,程序被结束掉了。

关于cgroup

cgroups(Control Groups)最初叫Process Container,由Google工程师(Paul Menage和Rohit Seth)于2006年提出,后来因为Container有多重含义容易引起误解,就在2007年更名为Control Groups,并被整合进Linux内核。
cgroups可以限制、记录、隔离进程组所使用的物理资源(包括:CPU、memory、IO等),是lxc (linux container)的基础之一。
看到这里是不是隐约感觉到了什么?是的,docker也用了它。
Docker背后的内核知识——cgroups资源限制

猜你喜欢

转载自blog.csdn.net/u012375924/article/details/78180722