Linux Cgroups

Linux Cgroups 是 Linux 内核中用来为进程设置资源限制的一个重要功能. Cgroups将进程进行分组, 然后对这一组进程进行统一的资源监控和限制。Cgroups当前有V1和V2版本,为了后续用于实现简单容器sdocker,这里只验证V1版本的cpu和memory子系统。

Linux可以通过如下命令来查看当前系统支持的cgroup子系统:

 linux: # cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset
cpu
cpuacct
blkio
memory
devices
freezer
net_cls
perf_event
net_prio
hugetlb
pids
linux: #

有的系统(debian8/suse12), cgroup.memory没有启用, 这时可能会影响到下面几个方面:

. 在/sys/fs/cgroup/memory下建立目录失败, 提示readonly;
. docker info里面也会有提示信息;
. 使用kubeadm安装kubernetes时会提示错误;

解决办法, 在/etc/default/grub文件中增加如下选项(debian使用update_grub, suse使用grub2-mkconfig, 然后reboot):

 linux: # cat /etc/default/grub  | grep cgroup_enable
GRUB_CMDLINE_LINUX="cgroup_enable=memory"
linux: #

Cgroup.CPU

对于Cgroup.CPU,限制cpu利用率主要通过修改下面两个文件来实现:

 /sys/fs/cgroup/cpu/cpu.cfs_quota_us
/sys/fs/cgroup/cpu/cpu.cfs_period_us

把cpu.cfs_quota_us / cpu.cfs_period_us(默认100000)的值作为可以使用的CPU的百分比。使用方法举例如下(摘录自附录网页):

 Examples
--------
. Limit a group to CPU worth of runtime. If period is 250ms and quota is also 250ms, the group will get
CPU worth of runtime every 250ms. # echo > cpu.cfs_quota_us /* quota = 250ms */
# echo > cpu.cfs_period_us /* period = 250ms */ . Limit a group to CPUs worth of runtime on a multi-CPU machine. With 500ms period and 1000ms quota, the group can get CPUs worth of
runtime every 500ms. # echo > cpu.cfs_quota_us /* quota = 1000ms */
# echo > cpu.cfs_period_us /* period = 500ms */ The larger period here allows for increased burst capacity. . Limit a group to % of CPU. With 50ms period, 10ms quota will be equivalent to % of CPU. # echo > cpu.cfs_quota_us /* quota = 10ms */
# echo > cpu.cfs_period_us /* period = 50ms */ By using a small period here we are ensuring a consistent latency
response at the expense of burst capacity.

针对Cgroup.CPU进行测试,对于如下的cpu密集型程序, 启动后从top中可以看到cpu占用100%:

 linux: # cat cpu.c
int main(void) {
for (; ;); return ;
}
linux: #
 PID USER      PR  NI    VIRT    RES    SHR S   %CPU  %MEM     TIME+ COMMAND
root R 100.00 0.002 :33.02 cpu

通过给cpu.cfs_quota_us赋值20000,同时把程序pid赋值给tasks文件,让程序只能使用1/5的cpu。

 linux: # mkdir /sys/fs/cgroup/cpu/sdocker
linux: # mkdir /sys/fs/cgroup/cpu/sdocker/
linux: # echo > /sys/fs/cgroup/cpu/sdocker//cpu.cfs_quota_us
linux: # echo > /sys/fs/cgroup/cpu/sdocker//tasks

设置后立即生效,top可以看到进程cpu占用率在20%左右波动:

 PID USER      PR  NI    VIRT    RES    SHR S   %CPU  %MEM     TIME+ COMMAND
root R 20.202 0.002 :57.80 cpu

退出程序并清理cgroup资源:

 linux: # kill -
linux: # rmdir /sys/fs/cgroup/cpu/sdocker//

Cgroup.Memory

/sys/fs/cgroup/memory下定义了Cgroup.Memory子系统的相关文件, 各文件含义如下:

  cgroup.event_control       #用于eventfd的接口
memory.usage_in_bytes #显示当前已用的内存字节数
memory.limit_in_bytes #设置/显示当前限制的内存额度, 当usage_in_bytes超限时, 如果memory.swappiness配置可使用swap, kernel会优先把内存数据转移到swap空间, 最后若转移swap失败, 则根据memory.oom_control判断是否触发oom
memory.failcnt #显示内存使用量达到限制值的次数, 当usage_in_bytes超限时, 会触发该值增加
memory.max_usage_in_bytes #历史内存最大使用量
memory.soft_limit_in_bytes #设置/显示当前限制的内存软额度
memory.stat #显示当前cgroup的内存使用情况
memory.use_hierarchy #设置/显示是否将子cgroup的内存使用情况统计到当前cgroup里面
memory.force_empty #触发系统立即尽可能的回收当前cgroup中可以回收的内存
memory.pressure_level #设置内存压力的通知事件,配合cgroup.event_control一起使用
memory.swappiness #设置和显示当前的swappiness
memory.move_charge_at_immigrate #设置当进程移动到其他cgroup中时,它所占用的内存是否也随着移动过去
memory.oom_control #设置/显示oom controls相关的配置, 默认0启用
memory.numa_stat #显示numa相关的内存

针对Cgroup.Memory进行测试,如下的测试代码通过不断分配内存来触发内存限制功能:

 linux: # cat memory.cpp
#include <unistd.h> #include <csignal>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
using std::vector; vector<int *> g_mem_pointer; void sig_handler(int sig) {
printf("\n%d handle\n", sig);
for (auto p : g_mem_pointer) {
free(p);
} exit(-);
} int main(void) {
unsigned total_mem = , chunk_size = * ; signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler); int *p;
while () {
if (NULL == (p = (int *)malloc(chunk_size))) {
printf("[-] malloc failed!\n");
kill(getpid(), );
} memset(p, 0xff, chunk_size);
g_mem_pointer.push_back(p);
total_mem += chunk_size;
printf("[+] malloc size: %u\n", total_mem);
sleep();
} return ;
}
linux: #

memory.cpp

设置内存限制6m到memory.limit_in_bytes,同时把进程pid设置到tasks文件, 一段时间后可以看到进程oom-kill.

测试发现进程实际打印分配的总内存远远大于设置的内存上限时,  memory.usage_in_bytes中的数值才会慢慢趋近于memory.limit_in_bytes,即使设置memory.swappiness为0也如此;

 linux:~ # mkdir /sys/fs/cgroup/memory/sdocker
linux:~ # mkdir /sys/fs/cgroup/memory/sdocker/
linux:~ # echo 6m > /sys/fs/cgroup/memory/sdocker//memory.limit_in_bytes
linux:~ # cat /sys/fs/cgroup/memory/sdocker//memory.limit_in_bytes linux:~ # echo > /sys/fs/cgroup/memory/sdocker//tasks
linux:~ # rmdir /sys/fs/cgroup/memory/sdocker/

参考网址:

 https://segmentfault.com/u/wuyangchun
https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt

容器基础(三): 使用Cgroups进行资源限制的更多相关文章

  1. linux(centos8):使用cgroups做资源限制

    一,什么是cgroups? 1,cgroups是资源的控制组,它提供了一套机制用于控制一组特定进程对资源的使用.     cgroups绑定一个进程集合到一个或多个限制资源使用的子系统上. 2, cg ...

  2. docker容器基础

    一.docker容器基础6种名称空间:UTS.MOunt.IPC.PID.User.Net (1) Linux Namespaces:namespace 系统调用参数 隔离内容 内核版本  UTS   ...

  3. C++ 顺序容器基础知识总结

    0.前言 本文简单地总结了STL的顺序容器的知识点.文中并不涉及具体的实现技巧,对于细节的东西也没有提及.一来不同的标准库有着不同的实现,二来关于具体实现<STL源码剖析>已经展示得全面细 ...

  4. Bootstrap <基础三十>Well

    Well 是一种会引起内容凹陷显示或插图效果的容器 <div>.为了创建 Well,只需要简单地把内容放在带有 class .well 的 <div> 中即可.下面的实例演示了 ...

  5. day 53-1 Django基础三之视图函数

    Django基础三之视图函数   本节目录 一 Django的视图函数view 二 CBV和FBV 三 使用Mixin 四 给视图加装饰器 五 Request对象 六 Response对象 一 Dja ...

  6. day 67 Django基础三之视图函数

    Django基础三之视图函数   本节目录 一 Django的视图函数view 二 CBV和FBV 三 使用Mixin 四 给视图加装饰器 五 Request对象 六 Response对象 一 Dja ...

  7. Django基础三之路由、视图、模板

    Django基础三之路由.视图.模板 目录 Django基础三之路由.视图.模板 1. Django 请求和返回周期 1.1 路由层之路由匹配 1.2 有名分组 1.3 无名分组 2. 反射解析 3. ...

  8. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  9. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

随机推荐

  1. GoBelieve Android SDK接入备忘

    Android SDK版本 目前SDK只支持Android 2.2或以上版本的手机系统. AndroidManifest.xml配置 以下配置可以在IMDemo/AndroidManifest.xml ...

  2. Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)

    最近在看Unity官方的AssetBundle(以下简称AB)的教程,也照着做了一遍,不过做出来的AssetBundleManager的API设计得有些不太习惯.目前想到了一个可行的解决方案.AB相关 ...

  3. 名词解释-FrameWork

    直接翻译的意思是架构,但这样说可能不懂,下面我从两个方面来给你说吧: 一是比喻来说,假设你现在要盖楼房,framework就好比一个建筑公司,它里面有专门采集石料的,专门的租夹板的,专门的磨砂,搬砖的 ...

  4. 【转】opatch学习

    [转自:https://yq.aliyun.com/articles/28007,仅作学习用途] Opatch 是oracle公司开发的安装,卸载,检测patch冲突的工具,管理oracle所有已经安 ...

  5. 配置JAVA_HOME踩得坑 。。

    配置JAVA_HOME 的时候这里不能有空格哦 ,还以为什么呢...

  6. 查看系统PCI设备

    # lspci Host bridge:主板 VGA compatible controller:VGA显卡设备 Class 0403:声卡设备 USB Controller:USB接口设备 SATA ...

  7. ubuntu各系统双网卡绑定

    Ubuntu14.04双网卡绑定 2.1 确定网卡名称 首先确定两块网卡的名称,一般为eth0.eth1,如果有自己添加的网卡名称可能不同,在安装系统的时候可以看到,通过ipmaddr命令可以查看所有 ...

  8. java程序执行系统命令

    String cmd="orakill orcl 1233";//解锁数据库表 Process proc = Runtime.getRuntime().exec(cmd);

  9. js中String 转化为 Date

    <script> var s=["2008-8-1","2009/9/2","10/3/2010"]; for(var i=0; ...

  10. 【mysql处理远程登陆授权及数据库迁移备份问题】

    Database changedMariaDB [mysql]> grant all PRIVILEGES on mysql.* to root@'%' identified by '123'; ...