什么是cgroup:

Cgroups 是 control groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组
(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。最初由 google 的
工程师提出,后来被整合进 Linux 内核。Cgroups 也是 LXC 为实现虚拟化所使用的资源管理手段,
可以说没有cgroups就没有LXC。

cgroup可以干什么:

1.限制进程组可以使用的资源数量,限制进程最大使用的内存等
2.进程组的优先级控制,比如为某个进程组分配特定的cpu share
3.记录进程组使用的资源数量,比如记录某个进程CPU的使用时间
4.进程组隔离,比如通过namespace以达到隔离的目的
5.进程组控制,比如可以将进程组挂起或恢复

在Cgroup可以说理解了这四个概念,那么对于如何使用cgroup,将会是如鱼得水。

Subsystems: 称之为子系统,一个子系统就是一个资源控制器,比如 cpu子系统就是控制
cpu时间分配的一个控制器。
Hierarchies: 可以称之为层次体系也可以称之为继承体系,指的是Control Groups是
按照层次体系的关系进行组织的。
Control Groups: 一组按照某种标准划分的进程。进程可以从一个Control Groups迁移
到另外一个Control Groups中,同时Control Groups中的进程也会受到这个组的资源限制。
Tasks: 在cgroups中,Tasks就是系统的一个进程。

在Red_Hat_Enterprise_Linux-6系列的linux中,默认提供了如下子系统。

blkio这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等) 。
cpu这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
cpuacct这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
cpuset这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
devices这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
freezer这个子系统挂起或者恢复 cgroup 中的任务。
memory这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
net_cls这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序
(tc)识别从具体 cgroup 中生成的数据包。
ns名称空间子系统。

cgroup ##(此例是在redhat6.5中做测试)
cgroups 实现了对资源的配额和度量.(此例中凡是需要/etc/init.d/cgconfig restart 均需跳出cgroup目录进行操作,否则会重启失败)

[root@server1 ~]# yum search cgroup  寻找软件包
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
LoadBalancer | 3.9 kB 00:00
rhel-source | 3.9 kB 00:00
salt | 2.9 kB 00:00
=================================== N/S Matched: cgroup ====================================
libcgroup.i686 : Tools and libraries to control and monitor control groups
libcgroup.x86_64 : Tools and libraries to control and monitor control groups
libcgroup-devel.i686 : Development libraries to develop applications that utilize control
: groups
libcgroup-devel.x86_64 : Development libraries to develop applications that utilize control
: groups

Name and summary matches only, use "search all" for everything.
[root@server1 ~]# yum install libcgroup.x86_64 -y 安装软件包
安装好libcgroup之后,会在根下产生/cgroup,此时该目录下还没有任何东西
/etc/init.d/cgconfig start 打开cgroup(注意不能在当前目录下)

Docker容器学习 --- cgroup搭建_sed

[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
[root@server1 cgroup]# pwd
/cgroup
[root@server1 cgroup]# /etc/init.d/cgconfig start 开启cgconfig服务
Starting cgconfig service: [ OK ]
[root@server1 cgroup]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# ll
total 0
drwxr-xr-x 2 root root 0 Aug 21 15:39 blkio
drwxr-xr-x 2 root root 0 Aug 21 15:39 cpu
drwxr-xr-x 2 root root 0 Aug 21 15:39 cpuacct
drwxr-xr-x 2 root root 0 Aug 21 15:39 cpuset
drwxr-xr-x 2 root root 0 Aug 21 15:39 devices
drwxr-xr-x 2 root root 0 Aug 21 15:39 freezer
drwxr-xr-x 2 root root 0 Aug 21 15:39 memory
drwxr-xr-x 2 root root 0 Aug 21 15:39 net_cls
[root@server1 cgroup]# pwd
/cgroup

Docker容器学习 --- cgroup搭建_进程组_02

[root@server1 cgroup]# cd memory/
[root@server1 memory]# ls
cgroup.event_control memory.memsw.limit_in_bytes memory.swappiness
cgroup.procs memory.memsw.max_usage_in_bytes memory.usage_in_bytes
memory.failcnt memory.memsw.usage_in_bytes memory.use_hierarchy
memory.force_empty memory.move_charge_at_immigrate notify_on_release
memory.limit_in_bytes memory.oom_control release_agent
memory.max_usage_in_bytes memory.soft_limit_in_bytes tasks
memory.memsw.failcnt memory.stat
[root@server1 memory]# cat memory.limit_in_bytes
9223372036854775807
[root@server1 memory]# free -m 查看空闲内存大小
total used free shared buffers cached
Mem: 490 332 157 0 32 165
-/+ buffers/cache: 134 355
Swap: 991 0 991
[root@server1 memory]# df 查看挂载
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 19134332 1204464 16957888 7% /
tmpfs 251124 36 251088 1% /dev/shm
/dev/vda1 495844 33478 436766 8% /boot

Docker容器学习 --- cgroup搭建_进程组_03


tmpfs临时文件系统:

tmpfs,临时文件系统,是一种基于内存的文件系统,它和虚拟磁盘ramdisk比较类似像,但不完全相同,
和ramdisk一样,tmpfs可以使用RAM,但它也可以使用swap分区来存储,而且传统的ramdisk是个块设备,
要用mkfs来格式化它,才能真正地使用它;而tmpfs是一个文件系统,并不是块设备,只是安装它,就可以
使用了。tmpfs是最好的基于RAM的文件系统。
[root@server1 memory]# cat /etc/fstab  查看默认挂载可以看到临时文件系统

#
# /etc/fstab
# Created by anaconda on Fri Jul 27 11:46:21 2018
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=2f7fafc6-5946-4115-b837-692b2d7b4c31 /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@server1 memory]# bc
bc命令是一种支持任意精度的交互执行的计算器语言。bash内置了对整数四则运算的支持,但是并不
支持浮点运算,而bc命令可以很方便的进行浮点运算,当然整数运算也不再话下。
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
200*1024*1024
209715200
(interrupt) Exiting bc. ctrl+c可以退出

Docker容器学习 --- cgroup搭建_sed_04

[root@server1 memory]# vim /etc/cgconfig.conf 
group x1 {
memory {
memory.limit_in_bytes = 209715200; 限制最大内存数
}
[root@server1 memory]# /etc/init.d/cgconfig restart 重启服务必须在路径之外,因为是挂载的方式
Stopping cgconfig service: cgclear failed with Device or resource busy
[ OK ]
Starting cgconfig service: Error: cannot mount memory to /cgroup/memory: Device or resource busy
/sbin/cgconfigparser; error loading /etc/cgconfig.conf: Cgroup mounting failed
Failed to parse /etc/cgconfig.conf [FAILED]
[root@server1 memory]# cd
[root@server1 ~]# /etc/init.d/cgconfig restart 重启服务成功
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]

Docker容器学习 --- cgroup搭建_进程组_05

[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd memory/
[root@server1 memory]# ls
cgroup.event_control memory.memsw.limit_in_bytes memory.swappiness
cgroup.procs memory.memsw.max_usage_in_bytes memory.usage_in_bytes
memory.failcnt memory.memsw.usage_in_bytes memory.use_hierarchy
memory.force_empty memory.move_charge_at_immigrate notify_on_release
memory.limit_in_bytes memory.oom_control release_agent
memory.max_usage_in_bytes memory.soft_limit_in_bytes tasks
memory.memsw.failcnt memory.stat x1
[root@server1 memory]# cd x1/
[root@server1 x1]# ls
cgroup.event_control memory.memsw.limit_in_bytes memory.swappiness
cgroup.procs memory.memsw.max_usage_in_bytes memory.usage_in_bytes
memory.failcnt memory.memsw.usage_in_bytes memory.use_hierarchy
memory.force_empty memory.move_charge_at_immigrate notify_on_release
memory.limit_in_bytes memory.oom_control tasks
memory.max_usage_in_bytes memory.soft_limit_in_bytes
memory.memsw.failcnt memory.stat
[root@server1 x1]# cat memory.limit_in_bytes
209715200

Docker容器学习 --- cgroup搭建_sed_06


dd命令的解释:

dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
注意:指定数字的地方若以下列字符结尾则乘以相应的数字:b=512;c=1;k=1024;w=2
参数:
1. if=文件名:输入文件名,缺省为标准输入。即指定源文件。< if=input file >
2. of=文件名:输出文件名,缺省为标准输出。即指定目的文件。< of=output file >
3. ibs=bytes:一次读入bytes个字节,即指定一个块大小为bytes个字节。
obs=bytes:一次输出bytes个字节,即指定一个块大小为bytes个字节。
bs=bytes:同时设置读入/输出的块大小为bytes个字节。
4. cbs=bytes:一次转换bytes个字节,即指定转换缓冲区大小。
5. skip=blocks:从输入文件开头跳过blocks个块后再开始复制。
6. seek=blocks:从输出文件开头跳过blocks个块后再开始复制。
注意:通常只用当输出文件是磁盘或磁带时才有效,即备份到磁盘或磁带时才有效。
7. count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。
8. conv=conversion:用指定的参数转换文件。
[root@foundation38 docker]# cd /dev/shm/
[root@foundation38 shm]# ls
pulse-shm-1204051373 pulse-shm-2867013393 pulse-shm-367697894
pulse-shm-1494599866 pulse-shm-3297685066 spice.20894
pulse-shm-2486810400 pulse-shm-3457893269
[root@foundation38 shm]# dd if=/dev/zero of=file1 bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 0.486747 s, 2.2 GB/s
[root@foundation38 shm]# free -m
total used free shared buff/cache available
Mem: 3838 1656 118 1280 2063 576
Swap: 3839 11 3828
[root@foundation38 shm]# rm -f file1
[root@foundation38 shm]# ls
pulse-shm-1204051373 pulse-shm-2867013393 pulse-shm-367697894
pulse-shm-1494599866 pulse-shm-3297685066 spice.20894
pulse-shm-2486810400 pulse-shm-3457893269

Docker容器学习 --- cgroup搭建_sed_07

[root@server1 x1]# cd /dev/shm/
[root@server1 shm]# ls
[root@server1 shm]# free -m 查看空闲内存命令
total used free shared buffers cached
Mem: 490 333 157 0 32 165
-/+ buffers/cache: 135 355
Swap: 991 0 991
[root@server1 shm]# vmstat 查看空闲内存命令
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 161176 33212 169544 0 0 87 59 34 35 1 0 97 2 0
[root@server1 shm]# free -m
total used free shared buffers cached
Mem: 490 333 157 0 32 165
-/+ buffers/cache: 135 355
Swap: 991 0 991
[root@server1 shm]# dd if=/dev/zero of=file1 bs=1M count=300
dd: writing `file1': No space left on device
246+0 records in
245+0 records out
257114112 bytes (257 MB) copied, 0.305802 s, 841 MB/s
[root@server1 shm]# id
uid=0(root) gid=0(root) groups=0(root)

Docker容器学习 --- cgroup搭建_bc_08

[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300
dd: writing `file1': No space left on device 显示没有的空间用于截取命令
246+0 records in
245+0 records out
257114112 bytes (257 MB) copied, 0.183946 s, 1.4 GB/s
[root@server1 shm]# free -m
total used free shared buffers cached
Mem: 490 412 78 0 19 259
-/+ buffers/cache: 133 356
Swap: 991 48 943
[root@server1 shm]# rm -f file1
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=20
20+0 records in
20+0 records out
20971520 bytes (21 MB) copied, 0.0122048 s, 1.7 GB/s
[root@server1 shm]# rm -f file1
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=20
20+0 records in
20+0 records out
20971520 bytes (21 MB) copied, 0.0119196 s, 1.8 GB/s
[root@server1 shm]# free -m 查看内存使用情况
total used free shared buffers cached
Mem: 490 233 256 0 19 82
-/+ buffers/cache: 131 358
Swap: 991 0 991

Docker容器学习 --- cgroup搭建_bc_09

[root@server1 shm]# cd /cgroup/
[root@server1 cgroup]# cd memory/
[root@server1 memory]# ls
cgroup.event_control memory.memsw.limit_in_bytes memory.swappiness
cgroup.procs memory.memsw.max_usage_in_bytes memory.usage_in_bytes
memory.failcnt memory.memsw.usage_in_bytes memory.use_hierarchy
memory.force_empty memory.move_charge_at_immigrate notify_on_release
memory.limit_in_bytes memory.oom_control release_agent
memory.max_usage_in_bytes memory.soft_limit_in_bytes tasks
memory.memsw.failcnt memory.stat x1
[root@server1 memory]# cat memory.memsw.limit_in_bytes
9223372036854775807
[root@server1 memory]# cd
[root@server1 ~]# vim /etc/cg
cgconfig.conf cgrules.conf cgsnapshot_blacklist.conf
[root@server1 ~]# vim /etc/cgconfig.conf
group x1 {
memory {
memory.limit_in_bytes = 209715200;
memory.memsw.limit_in_bytes = 209715200; 限制最大内存数和swap分区的总和
}
[root@server1 ~]# /etc/init.d/cgconfig restart 因为是挂载的,所以得切换出来进行重启
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]

Docker容器学习 --- cgroup搭建_进程组_10

[root@server1 ~]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300
300+0 records in
300+0 records out
314572800 bytes (315 MB) copied, 0.498938 s, 630 MB/s
[root@server1 ~]# free -m
total used free shared buffers cached
Mem: 490 437 52 0 19 281
-/+ buffers/cache: 136 354
Swap: 991 0 991
[root@server1 ~]# ls
file1
[root@server1 ~]# cd /dev/shm/
[root@server1 shm]# ls
file1
[root@server1 shm]# rm file1
rm: remove regular file `file1'? y
那么如何在进程启动的时候就将其添加到control group中的呢,cgroup提供了一个cgexec命令用来达到这个目的。
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300
Killed
因为配置文件中指定为200M,所以当截取内存大于200M时没办法截取

Docker容器学习 --- cgroup搭建_sed_11

[root@server1 shm]# free -m
total used free shared buffers cached
Mem: 490 413 76 0 19 261
-/+ buffers/cache: 131 358
Swap: 991 0 991
[root@server1 shm]# rm -f file1
[root@server1 shm]# free -m
total used free shared buffers cached
Mem: 490 214 275 0 19 63
-/+ buffers/cache: 131 358
Swap: 991 0 991
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=190
190+0 records in
190+0 records out
199229440 bytes (199 MB) copied, 0.105252 s, 1.9 GB/s
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=200 只可以截取小于200M的内存
Killed

Docker容器学习 --- cgroup搭建_sed_12

[root@server1 shm]# pwd
/dev/shm
[root@server1 shm]# cd
[root@server1 ~]# ls
file1 memapp1 memapp2
[root@server1 ~]# rm -f file1
[root@server1 ~]# ls
memapp1 memapp2
[root@server1 ~]# chmod +x memapp* 加入执行权限
[root@server1 ~]# ls
memapp1 memapp2
[root@server1 ~]# ./memapp1
-bash: ./memapp1: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
[root@server1 ~]# yum install /lib/ld-linux.so.2 -y

Docker容器学习 --- cgroup搭建_sed_13

[root@server1 ~]# ./memapp1   运行脚本

Process ID is: 12765

Grabbing 4096 pages of memory

Success!

Press any key to exit

[root@server1 ~]# ./memapp2 运行脚本

Process ID is: 12766

Grabbing 8192 pages of memory

Success!

Press any key to exit

[root@server1 ~]#

Docker容器学习 --- cgroup搭建_sed_14

[root@server1 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
5000*4*1024
20480000
^C
(interrupt) Exiting bc.
[root@server1 ~]# vim /etc/cgconfig.conf
group x1 {
memory {
memory.limit_in_bytes = 20480000;
memory.memsw.limit_in_bytes = 20480000; 指定最大内存数和swap分区数总和
}
}
[root@server1 ~]# /etc/init.d/cgconfig restart
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]
[root@server1 ~]# useradd xfl 建立用户
[root@server1 ~]# cd /dev/shm/
[root@server1 shm]# ll -d
drwxrwxrwt 2 root root 60 Aug 21 16:51 .
[root@server1 shm]# su - xfl
[xfl@server1 ~]$ cd /dev/shm/
[xfl@server1 shm]$ ls
file1

Docker容器学习 --- cgroup搭建_bc_15

[xfl@server1 shm]$ logout 
[root@server1 shm]# rm -f file1
[root@server1 shm]# su - xfl
[xfl@server1 ~]$ ls
[xfl@server1 ~]$ quit
-bash: quit: command not found
[xfl@server1 ~]$ logout
[root@server1 shm]# su - xfl
[xfl@server1 ~]$ dd if=/dev/zero of=file1 bs=1M count=300M
3869+0 records in
3869+0 records out
4056940544 bytes (4.1 GB) copied, 47.0685 s, 86.2 MB/s

[xfl@server1 ~]$ rm -f file1
[xfl@server1 ~]$ ls
[xfl@server1 ~]$ logout
[root@server1 shm]# vim /etc/cgrules.conf
[root@server1 shm]# cat /etc/cgrules.conf | tail -n 2
xfl:memapp1 memory x1/
xfl:memapp2 memory x1/

Docker容器学习 --- cgroup搭建_bc_16

[root@server1 shm]# /etc/init.d/cgred start
Starting CGroup Rules Engine Daemon: [ OK ]
[root@server1 shm]# cd
[root@server1 ~]# ls
memapp1 memapp2
[root@server1 ~]# mv * /home/xfl/
[root@server1 ~]# ls
[root@server1 ~]# su - xfl
[xfl@server1 ~]$ ls
memapp1 memapp2
[xfl@server1 ~]$ ./memapp1 由于配置文件参数的限制,仅仅memapp1可以运行

Process ID is: 12900

Grabbing 4096 pages of memory

Success!

Press any key to exit

[xfl@server1 ~]$ ./memapp2

Process ID is: 12901

Grabbing 8192 pages of memory
Killed

Docker容器学习 --- cgroup搭建_进程组_17

[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# cd cpu
[root@server1 cpu]# cat cpu.shares
1024
[root@server1 cpu]# vim /etc/cgconfig.conf
group x2 {
cpu {
cpu.shares = 100; 在cpu.shares文件中,可以对进程调度程序所处理的进程组
设置CPU时间分配的比重。通过修改这个值,就可以在分组间调整CPU时间的比例。默认值为1024
}
}
[root@server1 cpu]# /etc/init.d/cgconfig restart 重启失败由于这个文件是挂载的方式
Stopping cgconfig service: cgclear failed with Device or resource busy
[ OK ]
Starting cgconfig service: Error: cannot mount cpu to /cgroup/cpu: Device or resource busy
/sbin/cgconfigparser; error loading /etc/cgconfig.conf: Cgroup mounting failed
Failed to parse /etc/cgconfig.conf [FAILED]
[root@server1 cpu]# cd 出来当前路径
[root@server1 ~]# /etc/init.d/cgconfig restart 可以正常重启服务
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]

Docker容器学习 --- cgroup搭建_进程组_18

[root@server1 ~]# cgexec -g cpu:x2 dd if=/dev/zero of=/dev/null &
[1] 12926
[root@server1 ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 42
Stepping: 1
CPU MHz: 2491.904
BogoMIPS: 4983.80
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 4096K
NUMA node0 CPU(s): 0

Docker容器学习 --- cgroup搭建_进程组_19


由于cpu0无法查看,所以这里无法使用iotop演示,这个命令没有的话自己安装:

[root@server1 ~]# cd /sys/
[root@server1 sys]# ls
block bus class dev devices firmware fs hypervisor kernel module power
[root@server1 sys]# cd devices/
[root@server1 devices]# ls
LNXSYSTM:00 platform software tracepoint virtual
pci0000:00 pnp0 system uncore_cbox
[root@server1 devices]# cd system/
[root@server1 system]# ls
clocksource i8237 ioapic lapic memory timekeeping
cpu i8259 irqrouter machinecheck node
[root@server1 system]# cd cpu/ 可以看到由于虚拟机只有一个CPU,所以不可以查看CPU0
[root@server1 cpu]# ls
cpu0 cpufreq cpuidle kernel_max offline online possible present

Docker容器学习 --- cgroup搭建_sed_20

[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd blkio/
[root@server1 blkio]# ls
blkio.io_merged blkio.throttle.io_service_bytes blkio.weight_device
blkio.io_queued blkio.throttle.io_serviced cgroup.event_control
blkio.io_service_bytes blkio.throttle.read_bps_device cgroup.procs
blkio.io_serviced blkio.throttle.read_iops_device notify_on_release
blkio.io_service_time blkio.throttle.write_bps_device release_agent
blkio.io_wait_time blkio.throttle.write_iops_device tasks
blkio.reset_stats blkio.time
blkio.sectors blkio.weight
[root@server1 blkio]# ll /dev/vda
brw-rw---- 1 root disk 252, 0 Aug 21 15:35 /dev/vda

Docker容器学习 --- cgroup搭建_bc_21


限制读写速度:

[root@server1 ~]# vim /etc/cgconfig.conf   252:0是/dev/vda这个块设备的信息
[root@server1 ~]# /etc/init.d/cgconfig restart
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]

Docker容器学习 --- cgroup搭建_sed_22

[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# cd blkio/
[root@server1 blkio]# ls
blkio.io_merged blkio.throttle.io_service_bytes blkio.weight_device
blkio.io_queued blkio.throttle.io_serviced cgroup.event_control
blkio.io_service_bytes blkio.throttle.read_bps_device cgroup.procs
blkio.io_serviced blkio.throttle.read_iops_device notify_on_release
blkio.io_service_time blkio.throttle.write_bps_device release_agent
blkio.io_wait_time blkio.throttle.write_iops_device tasks
blkio.reset_stats blkio.time x3
blkio.sectors blkio.weight
[root@server1 blkio]# cd x3/
[root@server1 x3]# ls
blkio.io_merged blkio.sectors blkio.time
blkio.io_queued blkio.throttle.io_service_bytes blkio.weight
blkio.io_service_bytes blkio.throttle.io_serviced blkio.weight_device
blkio.io_serviced blkio.throttle.read_bps_device cgroup.event_control
blkio.io_service_time blkio.throttle.read_iops_device cgroup.procs
blkio.io_wait_time blkio.throttle.write_bps_device notify_on_release
blkio.reset_stats blkio.throttle.write_iops_device tasks
[root@server1 x3]# cat blkio.throttle.read_bps_device
252:0 1000000

Docker容器学习 --- cgroup搭建_sed_23


使用iotop查看进程,没有的话安装yum install iotop -y,可以看到速度大致为设定的1000K/s,可以看到相应的进程():

cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null &
# 在/dev/vda上读数据,查看速度

Docker容器学习 --- cgroup搭建_sed_24


使用–privileged=true参数给容器内阿设置权限:

[root@foundation38 Desktop]# docker run --rm -it --device-read-bps /dev/sda:1M --privileged=true ubuntu
root@dd09a2aeee7b:/# fdisk -l

Disk /dev/sda: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders, total 625142448 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a2177

Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 625141759 311521280 8e Linux LVM
root@dd09a2aeee7b:/# dd if=/dev/sda of=/dev/null bs=1M count=2
2+0 records in
2+0 records out
2097152 bytes (2.1 MB) copied, 1.99238 s, 1.1 MB/s 可以看到速度跟限定速度相近

Docker容器学习 --- cgroup搭建_sed_25


cgroup子系统3_freezer子系统:

freezer子系统用于挂起和恢复cgroup中的进程。freezer有一个控制文件:freezer.state,将FROZEN
写入该文件,可以将cgroup中的进程挂起,将THAWED写入该文件,可以将已挂起的进程恢复。通过遍历
cgroup中的进程,对其freeze或者wake_up。freeze操作通过freeze框架实现,设置进程的TIF_SIGPENDING
函数(伪信号),唤醒进程,然后进程在返回用户态时,信号处理入
口get_signal_to_deliver中通过try_to_freeze冻结进程(设置进程为TASK_UNINTERRUPTABLE,然后重调度)
[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd freezer/
[root@server1 freezer]# ls
cgroup.event_control cgroup.procs notify_on_release release_agent tasks
[root@server1 freezer]# cd
[root@server1 ~]# vim /etc/cgconfig.conf
[root@server1 ~]# /etc/init.d/cgconfig restart
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]

Docker容器学习 --- cgroup搭建_bc_26

[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd freezer/
[root@server1 freezer]# ls
cgroup.event_control cgroup.procs notify_on_release release_agent tasks x4
[root@server1 freezer]# cd x4/
[root@server1 x4]# ls
cgroup.event_control cgroup.procs freezer.state notify_on_release tasks
[root@server1 x4]# cat tasks
[root@server1 x4]# dd if=/dev/zero of=/dev/null &
[1] 13044

Docker容器学习 --- cgroup搭建_bc_27


使用top命令查看可以看到cpu占比:

Docker容器学习 --- cgroup搭建_sed_28

[root@server1 x4]# ps ax
PID TTY STAT TIME COMMAND
12980 pts/1 Ss 0:00 -bash
13044 pts/0 R 2:14 dd if=/dev/zero of=/dev/null
13050 pts/1 S+ 0:00 top
13051 pts/0 R+ 0:00 ps ax
[root@server1 x4]# ls
cgroup.event_control cgroup.procs freezer.state notify_on_release tasks
[root@server1 x4]# echo 13044 > tasks
[root@server1 x4]# cat freezer.state
THAWED
[root@server1 x4]# echo FROZEN > freezer.state 将进程挂起
[root@server1 x4]# cat freezer.state
FROZEN

Docker容器学习 --- cgroup搭建_进程组_29


使用top命令查看无法查看到后台运行的dd命令:

Docker容器学习 --- cgroup搭建_进程组_30

[root@server1 x4]# pwd
/cgroup/freezer/x4
[root@server1 x4]# ls
cgroup.event_control cgroup.procs freezer.state notify_on_release tasks
[root@server1 x4]# echo THAWED > freezer.state 将进程恢复
[root@server1 x4]#

Docker容器学习 --- cgroup搭建_bc_31


使用top命令查看可以查看到后台进程:

Docker容器学习 --- cgroup搭建_进程组_32

[root@server1 ~]# killall dd  将后台运行的dd服务关闭

Docker容器学习 --- cgroup搭建_sed_33