Linux Control Group(简称 cgroup)是一个用于限制、统计和隔离进程的资源的特性,它于 2006 年由 Google 的两位工程师开发,之后合入 2.6.24 版本的内核。那时 docker 正在 Google 内部兴起,本人推测正是前者催生了 cgroup。本文重点介绍如何用 cgroup 限制进程的资源。

在虚拟化领域,如 qemu-kvm 和 linux container,cgroup 用常用来限制以下类型的资源:

  • CPU time:进程占用的 CPU 时间
  • Memory:进程占用的物理内存
  • Block IO:进程访问块设备的 bandwidth 或 IOPS
  • Network IO:进程访问网络的 bandwidth 或 packages 的数量

以 ubuntu 14.04 为例,安装 cgroup:

$ apt-get install cgroup-bin cgroup-lite libcgroup1

安装完成后,cgroup 默认挂载在 /sys/fs/cgroup 上,该目录下共有 11 个 subsystem,关于它们的介绍请见官网文档,更为详细的介绍请见 redhat resource management guide,本文将用到 blkio, cpu, memory 和 net_cls 这四个 subsystem。

$ ls /sys/fs/cgroup/
blkio  cpu  cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls
net_prio  perf_event  systemd

Limit CPU Time

void main(){unsigned int i, end;end = 1024 * 1024 * 1024;for(i = 0; i < end; )i ++;
}

未限制 CPU 使用率前,上述代码的执行时间为:

$ time ./a.outreal   0m3.317s
user    0m3.312s
sys     0m0.000s

我们在 /sys/fs/cgroup 下新建一个名为 cpu_limit 的 cgroup,并设置该 cgroup 下的进程只能占用单个 CPU 10% 的使用率。

# cfs_period_us 表示 CPU 总时间片段,cfs_quota_us 表示分配给该 cgroup 的时间片段。
# 10000/100000 = 10%$ mkdir /sys/fs/cgroup/cpu_limit
$ echo 100000 > /sys/fs/cgroup/cpu_limit/cpu.cfs_period_us
$ echo 10000 > /sys/fs/cgroup/cpu_limit/cpu.cfs_quota_us

限制后上述代码的执行时间如下,约为前者的 10 倍:

$ time cgexec -g cpu:cpu_limit  ./a.outreal  0m31.904s
user    0m3.192s
sys     0m0.000s

某个时间点 top 的输出为:

$ top
......PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
28280 root      20   0    4196    668    592 R  10.0  0.0   0:01.28 a.out

Limit Memory

首先在 /sys/fs/cgroup/memory 下新建一个名为 limit_memory 的 cgroup:

$ mkdir /sys/fs/cgroup/memory/limit_memory

限制该 cgroup 的内存使用量为 300 MB:

# 物理内存 + SWAP <= 300 MB
$ echo 314572800 > /sys/fs/cgroup/memory/limit_memory/memory.limit_in_bytes
$ echo 0 > /sys/fs/cgroup/memory/limit_memory/memory.swappiness

下面是测试代码,它分十次申请内存,每次申请 100 MB:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>#define CHUNK_SIZE 1024 * 1024 * 100void main(){char *p;int i;for(i = 0; i < 10; i ++){p = malloc(sizeof(char) * CHUNK_SIZE);if(p == NULL){printf("fail to malloc!");return ;}memset(p, 0, CHUNK_SIZE);printf("malloc memory %d MB\n", (i + 1) * 100);}
}

执行结果如下,当进程占用的内存超过限制时,将被 kill。

$ cgexec -g memory:limit_memory ./a.out
malloc memory 100 MB
malloc memory 200 MB
Killed

Limit Block IO

我们采用 blkio 限制进程访问块设备的速率,以磁盘为例,未限制前,其读的带宽为:

$ dd if=in.file of=/dev/null count=1000 bs=1M
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 1.4419 s, 727 MB/s

采用以下方式配置 cgroup,限制磁盘的读取速率为 10MB/s

# 获取所读文件所在的磁盘编号,本文的编号为 252:0
$ df  -m
Filesystem                  1M-blocks  Used Available Use% Mounted on
/dev/mapper/ubuntu--vg-root     17755  6288     10543  38% /
...
$ ls -l /dev/mapper/ubuntu--vg-root
lrwxrwxrwx 1 root root 7 Jul 10 21:20 /dev/mapper/ubuntu--vg-root -> ../dm-0
$ ls -l /dev/dm-0
brw-rw---- 1 root disk 252, 0 Jul 10 21:20 /dev/dm-0# 在 /sys/fs/cgroup 目录下新建一个 cgroup,名为 limit_blkio
$ mkdir /sys/fs/cgroup/limit_blkio# 设置读速率为 10MB/s,其中 252:0 表示所读文件在的磁盘
$ echo "252:0 10485760" > /sys/fs/cgroup/blkio/limit_blkio/blkio.throttle.read_bps_device

再次执行 dd,其平均读速率为 10.5MB/s。

# 清楚内存的缓存数据
$ echo 3 > /proc/sys/vm/drop_caches$ cgexec -g blkio:limit_blkio dd if=in.file of=/dev/null count=1000 bs=1M
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 100.03 s, 10.5 MB/s

其中某个时刻 iotop 的输出如下:

Total DISK READ :       9.80 M/s | Total DISK WRITE :       0.00 B/s
Actual DISK READ:       9.80 M/s | Actual DISK WRITE:       0.00 B/sTID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
19987 be/4 root        9.80 M/s    0.00 B/s  0.00 % 96.99 % dd if=in.file of=/dev/null count=1000 bs=1M

test_limit 目录下有多个 blkio 相关的文件,较为常用的是以下四个:

  • blkio.throttle.read_bps_device:读取块设备的带宽
  • blkio.throttle.read_iops_device:读取块设备的 IOPS
  • blkio.throttle.write_bps_device:写块设备的带宽
  • blkio.throttle.write_iops_device:写块设备的 IOPS

Limit Network IO

未限速时,采用 scp 测试的网络速度为:

$ scp test.file root@10.10.1.180:~/
in.file                                            100% 1000MB  71.4MB/s   00:14

我们用 net_cls 标记某个 cgroup 下的包,借助 tc 来限制被标记的包的量,从而限制网络带宽:

$ mkdir /sys/fs/cgroup/net_cls/net_limit
$ echo 0x001000001 > net_cls.classid# 采用 tc 限制 classid 为 10:1 网络带宽为 40Mbit/s
$ tc qdisc add dev eth0 root handle 10: htb
$ tc class add dev eth0 parent 10: classid 10:1 htb rate 40mbit
$ tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup

限速后,采用 scp 测试的网络速度为 3.6 MB/s,注意到 3.6 MB/s 和 40 Mbit/s(5MB/s) 有较大差距,而 IP 和 TCP 头部额外的开销(共 40 字节头部,每个包的平均大小为 1448 字节)不可能造成如此大的差距,所以本人也、对此深感疑惑,但未能查明原因。

$ scp test.file root@10.10.1.180:~/
in.file                                         100% 1000MB   3.6MB/s   04:39

参考:
Linux Control Group 简介

LinuxControlGroup(Cgroup)简介相关推荐

  1. 【CGroup原理篇V1】一、CGroup 简介

    一.CGroup简介 CGroup,Control Group,是Linux Kernel对物理资源进行管控配置的一种机制,该机制允许聚集或分割进程集,包括他们将来所有的子任务到一个层级中,并附加指定 ...

  2. Cgroup简介-概述

    Cgroup(Control Groups)是这样一种机制:它以分组的形式对进程使用系统资源的行为进行管理和控制.也就是说,用户通过cgroup对所有进程进行分组,再对该分组整体进行资源的分配和控制. ...

  3. docker容器 cpu memory 资源限制

    目录 背景 cgroup简介 内存限制 内存限制相关的参数 用户内存限制 Memory reservation OOM killer 核心内存 Swappiness CPU 限制 概述 CPU 限制相 ...

  4. docker容器资源配额控制

    Docker通过cgroup来控制容器使用的资源配额,包括CPU.内存.磁盘三大方面,基本覆盖了常见的资源配额和使用量控制. cgroup简介 cgroup是Control Groups的缩写,是Li ...

  5. docker安全之容器资源控制 安全加固

    目录 一.cgroup简介 二. 容器资源控制 1.内存限制 ​2.cpu限额 ​3.Block IO限制 ​三.docker 安全加固 在使用 docker 运行容器时,默认的情况下,docker没 ...

  6. Rancher k8s 资源管理

    cgroup 简介 控制群组 (control group)(简称cgroup) 是 Linux kernel 的一项功能.从使用的角度看,cgroup 是一个目录树结构,目录中可以创建多层子目录,这 ...

  7. [漏洞分析] CVE-2022-0492 容器逃逸漏洞分析

    CVE-2022-0492 容器逃逸分析 文章目录 CVE-2022-0492 容器逃逸分析 漏洞简介 环境搭建 漏洞原理与相关知识 漏洞发生点 cgroup 简介 cgroup 使用 release ...

  8. android 内存管理

    文章目录 android 内存管理 其他参考 内存相关测评参考 进程间的内存分配 内存类型 内存页面 Attention! 内存不足管理 内核交换守护进程(Kswapd) 请求分页(Kswapd) 更 ...

  9. Docker学习(一)-----Docker简介与安装

    一.Docker介绍 1.1什么是docker Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植 ...

最新文章

  1. 解决远程桌面无法连接问题
  2. Memcache 笔记
  3. 开发日记-20190423 关键词 android静态代理类代理方法打断点debug 退出当前activity 闪退
  4. 一道关于 json 和 slice 的题难倒了 80% 的人
  5. 2020年9月编程语言排行榜:C语言继续第一,你站哪个?
  6. 关于目录操作walk
  7. 福建省计算机初级职称,2019福建助理工程师职称评定条件材料及审核管理制度...
  8. 年轻人应该买房还是租房,我给你理性分析
  9. mysql视图,总结
  10. 生物信息 Python 库 - Dash Bio 究竟厉害在哪里?
  11. paip.cache 缓存架构以及性能提升总结
  12. WebService学习总结(6)——WebService常用接口
  13. 使用Qt给微信头像添加国旗
  14. mysql入库字段编码导致报错 Incorrect string value: ‘\xF0\x9F\x91\xBD\xF0\x9F...‘ for column ‘content‘
  15. android 自定义indicator,Android自定义Indicator
  16. 华为OD 社招(Java后端)一面
  17. 提升工作效率五步走之后三步 2016-09-19 刘思佳 思佳真探
  18. 芯片解密STM32F100VB 芯片基本特性
  19. Strategy (策略)模式
  20. Git - 团队合作利器 Branch 与 Git Flow

热门文章

  1. python switch高效替代_Python中用什么代替switch
  2. 蔡徐坤团队获得”微博年度最佳团体“!vivo X23幻彩版却实力抢眼
  3. mongoDB cluster insert slow
  4. 各种initcall的执行先后顺序(module_init、postcore_initcall、arch_initcall、subsys_initcall、 fs_initcall)【转】...
  5. FTP服务器配置部分
  6. 电动葫芦使用注意事项(转载)
  7. PHP extension mcrypt must be loaded.
  8. MapReduce: map读取文件的过程
  9. 解决firefox字体发虚的问题
  10. SCOM 2007 R2监控系统安装部署(二)安装Operation Manager 2007 R2管理服务器