1  Cgroups简介

1.1 What are cgroups ?

Cgroups(控制组)是Linux内核的一个功能,用来限制、统计和分离一个进程组的资源(CPU、内存、磁盘输入输出等)。换句话说就是,如果一个进程加入了某一个控制组,该控制组对Linux的系统资源都有严格的限制,进程在使用这些资源时,不能超过其最大的限制数,例如:memory资源,如果加入控制组的进程使用的memory大于其限制,可能会出现OOM错误(关于OOM错误可参看Linux内核OOM机制分析)。cgroup本身提供将进程进行分组化管理的功能和接口的基础结构

控制组提供一种机制,将一组任务和它们的子任务聚合或划分到有特定功能的层级结构(hierarchical)中。在Cgroups中涉及下面的几个概念:

(1)任务(task):在 cgroups 中,任务就是系统的一个进程。

(2)控制族群(control group):控制族群就是一组按照某种资源限制划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到多个控制族群。假设这里有个进程A,我们要限制其使用的系统内存总量的10%,我们就可以创建一个memory占用10%的cgroups。然后,将进程A添加到cgroups,那么进程A最多占用内存总量的10%,当然,一个cgroups一般情况下不止一个进程。

(3)层级(hierarchy):控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。子控制组自动继承父节点的特定属性,当然子控制组还可以有自己特定的属性。下面是Linux内核关于Cgroups的一种图示:可以看出他的层级表示:

.CPU :          "Top cpuset"

/       \

CPUSet1         CPUSet2

|               |

(Professors)    (Students)

In addition (system tasks) are attached to topcpuset (so

that they can run anywhere) with a limit of 20%

Memory : Professors (50%), Students (30%), system (20%)

Disk : Professors (50%), Students (30%), system (20%)

Network : WWW browsing (20%), Network File System (60%), others (20%)

/ \

Professors (15%)  students (5%)

Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd goes

into the NFS network class.(参考Linux内核的cgroups说明)

(4)Subsystem:子系统是任务组中的一个模块,例如前面的memory就是一个子系统,该子系统是一个内存控制器。在cgroups的框架下,为cgroups提供多种资源限制。(each subsystem has system-specific state attached to each cgroup in the hierarchy.  Each hierarchy has an instance of the cgroup virtual filesystem associated with it)。

1.2  Cgroups子系统介绍

(1)blkio --为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等)。

(2)cpu -- 使用调度程序提供对cgroup-bin_0.38-1ubuntu2_i386版本中的cgconfig.conf文件,但是我们可以自己创建该配置文件,这样但mount , group and default 三个段,这三个段的顺序是任意的,并且都是可选参数,该文件中用

mount section has this form:

mount {

= ;

...

}

Controller:

表示内核支持的子系统的名字。通过/proc/cgroups文件查看系统中支持子系统。

Path:

子系统的挂载点。

如果没有mount段,则controllers不会被挂载。

group section has this form:

group {

[permissions]

{

= ;

...

}

...

}

Name:

control group的名字,只能包括目录名字允许的字符。
permissions:

可选项,指定cgroup对应的挂载点文件系统的权限

Controller:

内核中支持的子系统的名字。

param name,param value:参数的名字和参数的值。

如果没有group,则就没有group被创建。

Default段如下面的形式:

default {

perm {

task {

uid = ;

gid = ;

fperm =

}

admin {

uid = ;

gid = ;

dperm =

fperm =

}

}

}

下面举两个例子:

mount {#定义需要创建的cgroup子系统及其挂载点,这里创建cpu与cpuacct(统计)两个cgroup子系统

cpu = /mnt/cgroups/cpu;

cpuacct = /mnt/cgroups/cpu;

}

和下面的shell脚本是等价的:

mkdir /mnt/cgroups/cpu

mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/c

group daemons/www {

perm {#定义组的权限

task {

uid = root;

gid = webmaster;

fperm = 770;

}

admin {

uid = root;

gid = root;

dperm = 775;

fperm = 744;

}

}

cpu {

cpu.shares = "1000";

}

}

group daemons/ftp {

perm {

task {

uid = root;

gid = ftpmaster;

fperm = 774;

}

admin {

uid = root;

gid = root;

dperm = 755;

fperm = 700;

}

}

cpu {

cpu.shares = "500";

}

}

相当于使用下面的脚本:

mkdir /mnt/cgroups/cpu

mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/cpu

mkdir /mnt/cgroups/cpu/daemons

mkdir /mnt/cgroups/cpu/daemons/www

chown root:root /mnt/cgroups/cpu/daemons/www/*

chown root:webmaster /mnt/cgroups/cpu/daemons/www/tasks

echo 1000 > /mnt/cgroups/cpu/daemons/www/cpu.shares

上面的具体内容可以参考,cfconfig.conf文件说明

1.4 用户空间挂载Cgroup

上面我们分析了一下,cgroup的配置文件,这里我们具体分析一下使用命令如何进行配置。我们知道cgroup的实现有一个文件系统的支持,用户空间的配置可以使用cgroup文件系统。首先,我们可以创建一个层级:在创建层级之前我们需要创建挂载的目录,这里使用的目录是/home/ubuntu /test_cgroup

root@ubuntu:~# mount -t cgroup -o cpu cpu_group /home/ubuntu/test_cgroup/

这个命令就是创建了一个test_cgroup的层级,这个层级有一个子系统cpu,并把层级挂载到了/home/ubuntu /test_cgroup目录下。进入该目录可以看到一些和CPU相关的参数。

root@ubuntu:~# cd test_cgroup/

root@ubuntu:~/test_cgroup# ls

cgroup.clone_children  cpu.cfs_period_us  cpu.shares         tasks

cgroup.event_control   cpu.cfs_quota_us   cpu.stat       cgroup.procs           cpu.rt_period_us   notify_on_release

cgroup.sane_behavior   cpu.rt_runtime_us  release_agent

然后创建一个cgroup,名字为foo

root@ubuntu:~/test_cgroup# mkdir foo

root@ubuntu:~/test_cgroup# cd foo/

root@ubuntu:~/test_cgroup/foo# ls

cgroup.clone_children  cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release

cgroup.event_control   cpu.cfs_quota_us   cpu.shares         tasks

cgroup.procs           cpu.rt_period_us   cpu.stat

这样就在cpu_group层级上创建了一个foo的cgroup,在Foo目录下有一些文件,这些都是CPU相关的属性。其中cat ~/test_cgroup/task可以看到系统中的所有进程ID。这是因为每创建一个层级,系统会把系统中所以的进程ID添加到task中,而在foo/task文件却是空,这个文件用户可以添加。

在/proc/下面有一个cgroups的文件,记录了所有cgroups子系统的状态信息。

root@ubuntu:~/test_cgroup/foo# cat /proc/cgroups

#subsys_name    hierarchy num_cgroups            enabled

cpuset                   3                 1                 1

cpu      4                 3                 1

cpuacct                 5                 1                 1

memory                6                 2                 1

devices                  7                 1                 1

freezer                  8                 1                 1

blkio    9                 1                 1

perf_event           10              1                 1

hugetlb                  11              1                 1

从左到右的条目分别是子系统name,hierarchy ID,子系统的cgroup控制组数目,子系统是否可用(1可用,0不可用)

/proc/mounts文件显示了系统中挂载的文件系统信息,前面几个目录表示文件系统name,挂载点绝对路径,文件系统类型

root@ubuntu:~/test_cgroup/foo# cat /proc/mounts

rootfs / rootfs rw 0 0

sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0

proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0

udev /dev devtmpfs rw,relatime,size=503368k,nr_inodes=125842,mode=755 0 0

devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0

tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=102556k,mode=755 0 0

/dev/disk/by-uuid/612dacd9-3cf7-471b-92a4-f5c7c6e4e88a / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0

none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0

none /sys/fs/fuse/connections fusectl rw,relatime 0 0

none /sys/kernel/debug debugfs rw,relatime 0 0

none /sys/kernel/security securityfs rw,relatime 0 0

none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0

none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0

none /run/user tmpfs rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755 0 0

none /sys/fs/pstore pstore rw,relatime 0 0

systemd /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0

vmware-vmblock /run/vmblock-fuse fuse.vmware-vmblock rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other 0 0

gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0

cgroup /sys/fs/cgroup/cpuset cgroup rw,relatime,cpuset 0 0

cgroup /sys/fs/cgroup/cpu cgroup rw,relatime,cpu 0 0

cgroup /sys/fs/cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0

cgroup /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0

cgroup /sys/fs/cgroup/devices cgroup rw,relatime,devices 0 0

cgroup /sys/fs/cgroup/freezer cgroup rw,relatime,freezer 0 0

cgroup /sys/fs/cgroup/blkio cgroup rw,relatime,blkio 0 0

cgroup /sys/fs/cgroup/perf_event cgroup rw,relatime,perf_event 0 0

cgroup /sys/fs/cgroup/hugetlb cgroup rw,relatime,hugetlb 0 0

gvfsd-fuse /root/.gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=0,group_id=0 0 0

test_group /home/zfz/cgroup cgroup rw,relatime,cpu 0 0

cpu_group /home/zfz/test_cgroup cgroup rw,relatime,cpu 0 0

1.5  Cgroup使用实例

用lssubsys -al来列出系统支持多少种子系统,和使用ls /sys/fs/cgroup/ (ubuntu)来显示已经挂载的子系统。

如果提示下面的错误信息,则表示系统中还没有安装cgroup.

lssubsys -all

The program 'lssubsys' is currently not installed. You can install it by typing:

需要使用下面的方法进行安装:

root@ubuntu:~# apt-get install cgroup-bin

Reading package lists... Done

再次使用lssubsys列出系统中支持的子系统,根据不同的内核版本,支持的子系统也不相同。

root@ubuntu:~# lssubsys --all

cpuset

cpu

cpuacct

memory

devices

freezer

blkio

perf_event

hugetlb

还有一种情况需要进行确认,确认相应的内核部分是否已经编译。

grep CGROUP /boot/config-`uname -r`

CONFIG_CGROUPS=y

# CONFIG_CGROUP_DEBUG is not set

CONFIG_CGROUP_FREEZER=y

CONFIG_CGROUP_DEVICE=y

CONFIG_CGROUP_CPUACCT=y

CONFIG_CGROUP_HUGETLB=y

CONFIG_CGROUP_PERF=y

CONFIG_CGROUP_SCHED=y

CONFIG_BLK_CGROUP=y

# CONFIG_DEBUG_BLK_CGROUP is not set

CONFIG_NET_CLS_CGROUP=m

CONFIG_NETPRIO_CGROUP=m

我们可以创建一个cgroup的cpu子系统,创建完成之后就在该目录下有下面的属性文件可以进行设置。

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# ls

cgroup.clone_children  cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release

cgroup.event_control   cpu.cfs_quota_us   cpu.shares         tasks

cgroup.procs           cpu.rt_period_us   cpu.stat

使用cat命令查看其中的默认值。

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat cpu.cfs_quota_us

-1

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat cpu.cfs_period_us

100000

默认挂载在/sys/fs/cgroup/memory,可以通过cfconfig.conf文件查看默认的挂载点。这里有两个小的例子主要是为了测试cgroup对进程使用CPU和memeory的控制,这里使用两个Python脚本来模拟其中的效果。

例子1:设置该进程对CPU的占用率不能超过50%。

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# echo 50000 > cpu.cfs_quota_us

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat cpu.cfs_quota_us

50000

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# cat tasks

root@ubuntu:/sys/fs/cgroup/cpu/test_cpu# echo 9477 > tasks

使用的Python程序如下:

root@ubuntu:~# cat python_test_cpu.py

#!/usr/bin/env python

import os

pid_num = os.getpid()

print pid_num

var = 1

count = 1

while var == 1:

count = count + 1

count = 0

在没有把python的进程号添加到tasks中,该进程的CPU占用率接近95%。而把该进程ID添加到tasks中经过持续的观察,该进程的CPU使用率不超出50%,和在cgroup中设置的一致。

例子2:限制内存的使用率

Python代码如下:

root@ubuntu:~# cat python_test_memory.py

#!/usr/bin/env python

import os

import time

pid_num = os.getpid()

print pid_num

var = 1

a = "abcdefgh"

b = "abcdefgh"

c = ""

time.sleep(10)

#while var == 1:

for i in range(1,30000000):

c = "####".join([a,b]) + c

在没有使用cgroups机制的情况下,通过top命令查看该进程占用的memory情况如下:

持续观察一段时间基本维持在40%左右。在使用cgoup机制,限制在10M的情况下,其内存的占有率发生了变化。

root@ubuntu:/sys/fs/cgroup/memory/memory_test# echo 10M > memory.limit_in_bytes

root@ubuntu:/sys/fs/cgroup/memory/memory_test# cat memory.limit_in_bytes

10485760

过一小段时间会出现进程退出的情况,如下:进程被杀掉了。

root@ubuntu:~# ./python_test_memory.py

10608

[8]+  Killed                  ./python_test_memory.py

Killed

在这里也可以配置内核的OOM机制,默认值是开着呢。

root@ubuntu:/sys/fs/cgroup/memory/memory_test# cat memory.oom_control

oom_kill_disable 0

under_oom 0

在上面我们设置的是memory.limit_in_bytes 值,但在目录下还有一个memory.soft_limit_in_bytes 属性,,该值和 memory.limit_in_bytes 的差异是,memory.soft_limit_in_bytes这个限制并不会阻止进程使用超过限额的内存,只是在系统内存不足时,会优先回收超过限额的进程占用的内存,使之向限定值靠拢

通过上面的分析可以看出来,简单的说Cgroup就是限制了各个不同进程之间使用各种资源的能力。上面两个例子是最常用的CPU和内存,每一个内核子系统都有很多的配置选项信息,其中配置选项的含义可以参考Linux内核文档,Linux的Cgroup子系统解释。Cgroup做到对资源的限制访问,这对于Linux系统上的虚拟化和云计算提供了一种资源配置方式。

参考文献:

http://blog.chinaunix.net/uid-20940095-id-3294134.html

http://files.cnblogs.com/lisperl/cgroups介绍.pdf

Linux系统中cgroup功能介绍相关推荐

  1. linux子系统gdp调试,Linux系统中GDB功能汇总

    在Linux系统操作中,GDB是一款程序调试工具,且拥有多种功能,下面小编将针对GDB的功能给大家做个详细介绍,以便你对GDB有个详细的了解. 或许,各位比较喜欢那种图形界面方式的,像VC.BCB等I ...

  2. linux rps值大小,Linux系统中RPS/RFS介绍

    frankzfz2014-07-27 17:32 demo121:frankzfz您好: 我想请教一个问题,就是将写好的GenericApp项目(没有配置工具),我加入zigbee协议栈的配置工具后还 ...

  3. 在每个运行中运行多个查询_linux系统中运行级别介绍

    CentOS7.3学习笔记总结(五十)- linux系统中运行级别介绍 linux系统中的运行级别是操作系统运行时的功能级别,级别从0到6共7个功能级别,分别是: 0:停机 1:单用户模式 2:多用户 ...

  4. linux sudo命令全称,你知道Linux系统中的sudo 命令吗?

    今天小编要跟大家分享的文章是关于Linux系统中sudo命令介绍.熟悉Linux操作系统的小伙伴们你们是否了解sudo命令.sudo 表示 "superuser do". 它允许已 ...

  5. linux中bash的功能主要有,Linux系统中的Bash功能的介绍

    今天小编要跟大家分享的文章是关于Linux系统中的Bash功能的介绍.一个完整计算机的体系结构包括:硬件与软件,而软件又分为系统软件与应用软件,负责对硬件仅需管理与操作的是系统软件的内核部分,用户是无 ...

  6. jenkins linux虚拟机,Linux系统中jenkins使用的简单介绍

    jenkins是一个开放的软件平台,在Linux系统中的软件平台也不少,但是jenkins一直是比较受欢迎的那一个.本文就来简单介绍一下Linux系统中jenkins安装配置和使用. 安装jenkin ...

  7. linux常用删除空文件夹,Linux基础 linux系统中的批量删除文件与空文件删除的命令介绍...

    Linux基础教程linux系统中的批量删除文件与空文件删除的命令介绍 Linux资料下面删除文件或者目录命令rm(remove): Linux培训功能说明:删除文件或目录. 语 法:rm [-dfi ...

  8. linux下vim编辑器插件,为你介绍Linux系统中vim编辑器的实用插件!

    今天小编要跟大家分享的文章是关于Linux系统中vim编辑器的实用插件.Vim 是 Linux 下的常用文本编辑器,但也经常被称为是一个上古神器,因为它对于初学者而言相当不友好,也不好入门. Linu ...

  9. 深度Linux下的中望CAD软件,中望CAD Linux预装版的功能介绍,在Deepin和UOS下安装很简单...

    如果你使用的是Deepin和UOS操作系统,那么安装中望CAD Linux预装版非常的简单,只需要打开应用商店,然后搜索中望就可以对出来的结果进行安装了,下面介绍一下中望CAD Linux预装版的功能 ...

  10. linux bzip2 命令,Linux系统中bzip2命令的语法参数介绍

    从bzip2这个Linux命令字面上看,它是以个跟压缩有关的命令.事实也确实如此,bzip2 的功能就是用来压缩bz2文件.本文就来介绍一下Linux系统中bzip2命令的语法和参数. 语 法:bzi ...

最新文章

  1. think in java笔记_Thinking in java读书笔记 PDF 下载
  2. 大凉山的美术课,怎么就跟英特尔扯上关系了
  3. 国内外常用Linux服务器控制面板介绍
  4. Windows_API_函数 参考大全
  5. JVM编译时和运行时状态
  6. SAP 电商云 Spartacus UI 有状态 的 url 和 title 属性的赋值代码
  7. 小程序·云开发的HTTP API调用丨实战
  8. 你走过最长的路 ,就是机器学习过程中的弯路
  9. java毕设用的框架_分享四个Java低代码快速开发平台贼好用, 私活毕设神器
  10. 3 CO配置-企业结构-分配-把公司代码分配给成本控制范围
  11. API、H5跟风控相关的知识是否了解?
  12. 蓝桥杯 ALGO-122 算法训练 未名湖边的烦恼
  13. sql的left join 命令详解
  14. 安装windows7系统报错
  15. linux cp 复制目录下文件到另一个目录下
  16. flv格式php怎么播放不了,FLV格式视频不能在网页播放的解决办法
  17. (二)java项目中的文档转换案例实战——PDF转换为JPG图片压缩包
  18. 步道乐跑(最新版本)
  19. 计算机三级网络架构图,三级网络技术局域网基础:网络拓扑结构
  20. SQL Server 负载均衡集群方案之Moebius

热门文章

  1. 用友CDM系统“货位间商品移库单(一步)”表体增加“货位可用数量”字段,根据表头的选择的货位自动带出数值...
  2. python3 collections模块_python的Collections 模块
  3. Java NIO框架Netty教程(二)
  4. axios基于常见业务场景的二次封装
  5. 23.3. DELETE
  6. VC++多线程--进程间通信
  7. 异步消息的性能与激情之Netty开发思路
  8. js 正则清除html格式
  9. linux 复制文件时,报cp: omitting directory `XXX'
  10. IE css hack整理