Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。这个项目最先是由Google的工程师在2006年发起(主要是Paul Menage和Rohit Seth),最先的名称为进程容器(process containers)。在2007年时,由于在Linux内核中,容器(container)这个名词太过普遍,为避免混乱,被重命名为cgroup,而且被合并到2.6.24版的内核中去。而后,其它开始了他的发展。 Linux CGroupCgroup 可让您为系统中所运行任务(进程)的用户定义组群分配资源 — 比如 CPU 时间、系统内存、网络带宽或者这些资源的组合。您可以监控您配置的 cgroup,拒绝 cgroup 访问某些资源,甚至在运行的系统中动态配置您的 cgroup。
1 限制资源使用,好比内存使用上限以及文件系统的缓存限制。 2 优先级控制,CPU利用和磁盘IO吞吐。 3 一些审计或一些统计,主要目的是为了计费。 4 挂起进程,恢复执行进程。
1 cpu 子系统,主要限制进程的 cpu 使用率。 2 cpuacct 子系统,能够统计 cgroups 中的进程的 cpu 使用报告。 3 cpuset 子系统,能够为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。 4 memory 子系统,能够限制进程的 memory 使用量。 5 blkio 子系统,能够限制进程的块设备 io。 6 devices 子系统,能够控制进程可以访问某些设备。 7 net_cls 子系统,能够标记 cgroups 中进程的网络数据包,而后可使用 tc 模块(traffic control)对数据包进行控制。 8 net_prio — 这个子系统用来设计网络流量的优先级 9 freezer 子系统,能够挂起或者恢复 cgroups 中的进程。 10 ns 子系统,可使不一样 cgroups 下面的进程使用不一样的 namespace
11 hugetlb — 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统。
Cgred 是一个守护进程,它可根据在 /etc/cgrules.conf 文件中设定的参数将任务移动到 cgroup 中。/etc/cgrules.conf 文件中的条目可以使用以下两个格式之一: user hierarchies control_group user:command hierarchies control_group 例如: maria devices /usergroup/staff
这个条目指定任何属于名为 maria 用户的进程根据在 /usergroup/staff cgroup 中指定的参数访问设备子系统。要将具体命令与具体 cgroup 关联,请添加 command 参数,如下: maria:ftp devices /usergroup/staff/ftp
该条目现在指定何时名为 maria 的用户使用 ftp 命令,自动将该进程移动到包含 devices 子系统的层级中的 /usergroup/staff/ftp cgroup 中。请注意:该守护进程只有在符合适当的条件后才可将该进程移动到该 cgroup 中。因此,ftp 可能会在错误的组群中短暂运行。再有,如果该进程在错误组群中迅速生出子进程,则不会移动这些子进程。 /etc/cgrules.conf 文件中的条目可包括以下额外符号: @ - 当在 user 使用前缀时,代表是一个组群而不是单独用户。例如:@admins 是 admins 组群中的所有用户。 * - 代表“所有”。例如:subsystem 字段中的 * 代表所有子系统。 % - 代表与以上行中项目相同的项目。例如: @adminstaff devices /admingroup @labstaff % %
小结:经过cgroup设置咱们想要的规则,经过cgred将规则应用到进程之上html
[root@reddhat6_155_200 ~]# lssubsys -m cpuset /cgroup/cpuset cpu /cgroup/cpu cpuacct /cgroup/cpuacct memory /cgroup/memory devices /cgroup/devices freezer /cgroup/freezer net_cls /cgroup/net_cls blkio /cgroup/blkio
[root@reddhat6_155_200 ~]# vim /etc/cgconfig.conf #添加如下两段 group lesscpu{ cpu{ } } group morecpu{ cpu{ } }
[root@reddhat6_155_200 ~]# /etc/init.d/cgconfig restart Stopping cgconfig service: [肯定] Starting cgconfig service: [肯定] [root@reddhat6_155_200 ~]# ll /cgroup/cpu 总用量 0
--w--w--w-. 1 root root 0 2019-09-07 15:50 cgroup.event_control -rw-r--r--. 1 root root 0 2019-09-07 15:50 cgroup.procs -rw-r--r--. 1 root root 0 2019-09-07 15:50 cpu.cfs_period_us -rw-r--r--. 1 root root 0 2019-09-07 15:50 cpu.cfs_quota_us -rw-r--r--. 1 root root 0 2019-09-07 15:50 cpu.rt_period_us -rw-r--r--. 1 root root 0 2019-09-07 15:50 cpu.rt_runtime_us -rw-r--r--. 1 root root 0 2019-09-07 15:50 cpu.shares -r--r--r--. 1 root root 0 2019-09-07 15:50 cpu.stat drwxr-xr-x. 2 root root 0 2019-09-07 15:50 lesscpu #多出两个目录,和咱们定义的group名称是一至的 drwxr-xr-x. 2 root root 0 2019-09-07 15:50 morecpu -rw-r--r--. 1 root root 0 2019-09-07 15:50 notify_on_release -rw-r--r--. 1 root root 0 2019-09-07 15:50 release_agent -rw-r--r--. 1 root root 0 2019-09-07 15:50 tasks
[root@reddhat6_155_200 ~]# ll /cgroup/cpu 仔细观察能够发现每一个目录中的文件都是相同的,也就是默认状况下group会继承该子系统的全部规则 [root@reddhat6_155_200 ~]# ll /cgroup/cpu/morecpu/ [root@reddhat6_155_200 ~]# ll /cgroup/cpu/morecpu/
[root@reddhat6_155_200 ~]# cat /cgroup/cpu/cpu.shares #cpu.shares表示程序能够在 cgroup 中的任务可用的相对共享 CPU 时间的整数值,默认为1024 1024 [root@reddhat6_155_200 ~]# vim /etc/cgconfig.conf group lesscpu{ cpu{ cpu.shares=100; #该值不能够超过总大小(1024) } } group morecpu{ cpu{ cpu.shares=200; } } [root@reddhat6_155_200 ~]# /etc/init.d/cgconfig restart Stopping cgconfig service: [肯定] Starting cgconfig service: [肯定]
[root@reddhat6_155_200 ~]# cat /cgroup/cpu/lesscpu/cpu.shares
100
[root@reddhat6_155_200 ~]# cat /cgroup/cpu/morecpu/cpu.shares
200java
[root@reddhat6_155_200 ~]# lscpu |grep -A 1 "^CPU\(s\):" #查看当前CPU个数及在线个数 CPU(s): 2 On-line CPU(s) list: 0,1 [root@reddhat6_155_200 ~]# echo 0 > /sys/devices/system/cpu/cpu1/online #将cpu1下线,cpu0为主cpu没法下线 [root@reddhat6_155_200 ~]# lscpu |grep -A 1 "^CPU\(s\):" #查看在线状态,目前只有cpu0在线 CPU(s): 2 On-line CPU(s) list: 0
[root@reddhat6_155_200 ~]# cgexec -g cpu:lesscpu time dd if=/dev/zero of=/dev/null bs=1M count=200000 #窗口1 分配少的先执行 [root@reddhat6_155_200 ~]# cgexec -g cpu:morecpu time dd if=/dev/zero of=/dev/null bs=1M count=200000 #窗口2 [root@reddhat6_155_200 ~]# top #窗口3 使用top命令监控命令状态
注意观察两个dd命令CPU使用率linux
lesscpu结果:nginx
[root@reddhat6_155_200 ~]# cgexec -g cpu:lesscpu time dd if=/dev/zero of=/dev/null bs=1M count=200000 记录了200000+0 的读入 记录了200000+0 的写出 209715200000字节(210 GB)已复制,21.7357 秒,9.6 GB/秒 #注意CPU使用时间 0.01user 10.83system 0:21.73elapsed 33%CPU (0avgtext+0avgdata 7776maxresident)k #注意CPU使用率 0inputs+0outputs (0major+521minor)pagefaults 0swaps
morecpu结果:算法
[root@reddhat6_155_200 ~]# cgexec -g cpu:morecpu time dd if=/dev/zero of=/dev/null bs=1M count=200000 记录了200000+0 的读入 记录了200000+0 的写出 209715200000字节(210 GB)已复制,16.26 秒,12.9 GB/秒 0.02user 10.77system 0:16.26elapsed 66%CPU (0avgtext+0avgdata 7744maxresident)k 0inputs+0outputs (0major+519minor)pagefaults 0swaps
[root@reddhat6_155_200 ~]# cat /cgroup/memory/memory.limit_in_bytes #查看MEM(物理内存)默认限制大小 单位为字节 以目前机器配置,等同于无限制 9223372036854775807 [root@reddhat6_155_200 ~]# cat /cgroup/memory/memory.memsw.limit_in_bytes #查看MEM(物理内存)+Swap总的大小 此值必须大于等于 memory.limit_in_bytes 9223372036854775807 [root@reddhat6_155_200 ~]# vim /etc/cgconfig.conf #添加一个MEM 限制 group poormem{ memory{ memory.limit_in_bytes=268435456; #限制可使用内存大小为256M } [root@reddhat6_155_200 ~]# /etc/init.d/cgconfig restart Stopping cgconfig service: [肯定] Starting cgconfig service: [肯定]
[root@reddhat6_155_200 ~]# cat /cgroup/memory/poormem/memory.limit_in_bytes
268435456
[root@reddhat6_155_200 ~]# mkdir /mnt/tmpfs [root@reddhat6_155_200 ~]# mount -t tmpfs none /mnt/tmpfs #注意没有挂载源 使用none [root@reddhat6_155_200 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_redhat6demo01-lv_root 50G 5.4G 42G 12% / tmpfs 2.0G 224K 2.0G 1% /dev/shm /dev/vda1 477M 33M 419M 8% /boot /dev/mapper/vg_redhat6demo01-lv_home 5.5G 12M 5.2G 1% /home none 2.0G 0 2.0G 0% /mnt/tmpfs #大小2G,具体大小和系统剩余内存大小有关
[root@reddhat6_155_200 ~]# free -m #查看当前内存大小 total used free shared buffers cached Mem: 3959 2508 1451 2 246 1784
-/+ buffers/cache: 477 3482 Swap: 3967 0 3967 [root@reddhat6_155_200 ~]# dd if=/dev/zero of=/mnt/tmpfs/test bs=1M count=1000 #向 tmpfs 挂载点写入1G内存 记录了1000+0 的读入 记录了1000+0 的写出 1048576000字节(1.0 GB)已复制,0.466811 秒,2.2 GB/秒 [root@reddhat6_155_200 ~]# free -m #查看系统内存 少了1G total used free shared buffers cached Mem: 3959 3511 448 1002 246 2784
-/+ buffers/cache: 480 3479 Swap: 3967 0 3967 [root@reddhat6_155_200 ~]# rm -f /mnt/tmpfs/test #删除刚刚建立的文件 [root@reddhat6_155_200 ~]# free -m #查看当前剩余内存 total used free shared buffers cached Mem: 3959 2509 1450 2 246 1784
-/+ buffers/cache: 478 3481 Swap: 3967 0 3967
[root@reddhat6_155_200 ~]# cgexec -g memory:poormem dd if=/dev/zero of=/mnt/tmpfs/test bs=1M count=200 #配置的为256M 先建立一个200M 测试文件 记录了200+0 的读入 记录了200+0 的写出 209715200字节(210 MB)已复制,0.097221 秒,2.2 GB/秒 [root@reddhat6_155_200 ~]# rm -f /mnt/tmpfs/test [root@reddhat6_155_200 ~]# cgexec -g memory:poormem dd if=/dev/zero of=/mnt/tmpfs/test bs=1M count=300 #建立一个300M测试文件 挂了 很奇怪,按照文档说明此处不该该挂的,应该不够的会从Swap中读取 只有 memory.memsw.limit_in_bytes 也设置了才会限制从Swap中读取 不知道为啥??????
已杀死 [root@reddhat6_155_200 ~]# ll -h /mnt/tmpfs/test #查看大小只有
255M -rw-r--r--. 1 root root 255M 2019-09-07 22:03 /mnt/tmpfs/test
[root@reddhat6_155_200 ~]# cat /sys/block/vda/queue/scheduler #查看下当前系统磁盘调度算法 vda表示磁盘名称 noop anticipatory deadline [cfq] [root@reddhat6_155_200 ~]# cat /cgroup/blkio/blkio.weight #查看磁盘io权重默认值 1000 [root@reddhat6_155_200 ~]# vim /etc/cgconfig.conf #建立io限制规则 group lowio{ blkio{ blkio.weight=100; #设置io优先级 一个低 一个高 } } group highio{ blkio{ blkio.weight=200; } } group ddio{ blkio{ blkio.throttle.read_bps_device="252:0 1000000";
#限制程序读取磁盘的速度 252表示当前主盘符号 0表示副盘符号 1000000表示读取速率 单位为字节 即1M 须要注意的是,若是是物理设备 SCSI设备重启后主副盘符会发生变化 能够经过设置逻辑卷 } } [root@reddhat6_155_200 ~]# /etc/init.d/cgconfig restart Stopping cgconfig service: [肯定] Starting cgconfig service: [肯定]
[root@reddhat6_155_200 ~]# dd if=/dev/zero of=/root/bigfile1 bs=1M count=10000 #建立两个大的文件用于实验 [root@reddhat6_155_200 ~]# dd if=/dev/zero of=/root/bigfile2 bs=1M count=10000 [root@reddhat6_155_200 ~]# echo 3 > /proc/sys/vm/drop_caches #状况缓存 避免影响结果 [root@reddhat6_155_200 ~]# iotop #使用iotop命令监控io状态
新开两个窗口,分别使用lowio和highiovim
[root@reddhat6_155_200 ~]# cgexec -g blkio:lowio time cat /root/bigfile1 > /dev/null [root@reddhat6_155_200 ~]# cgexec -g blkio:highio time cat /root/bigfile2 > /dev/null
结果:当两个cat命令都读取时,使用highio磁盘速度大约是lowio的两倍缓存
当highio执行完成后lowio开始独占磁盘io网络
[root@reddhat6_155_200 ~]# cgexec -g blkio:lowio time cat /root/bigfile1 > /dev/null
0.08user 7.52system 0:40.54elapsed 18%CPU (0avgtext+0avgdata 2416maxresident)k 20480360inputs+0outputs (1major+182minor)pagefaults 0swaps [root@reddhat6_155_200 ~]# cgexec -g blkio:highio time cat /root/bigfile2 > /dev/null
0.08user 7.16system 0:32.64elapsed 22%CPU (0avgtext+0avgdata 2432maxresident)k 20480072inputs+0outputs (1major+183minor)pagefaults 0swaps
限制指定用户执行指定命令app
[root@reddhat6_155_200 ~]# vim /etc/cgrules.conf admin:dd blkio ddio/ #此行配置表示 admin用户执行dd命令时 使用 blkio子系统下ddio group进行限制 此处不只能够如今命令也能够如今程序 添加程序的启动命令便可 例 nginx java等 [root@reddhat6_155_200 ~]# /etc/init.d/cgred restart 正在中止 CGroup Rules Engine 守护进程...... [肯定] Starting CGroup Rules Engine Daemon: [肯定]
使用root用户测试dd命令less
[root@reddhat6_155_200 ~]# dd if=/tmp/bigfile1 of=/dev/null 记录了20480000+0 的读入 记录了20480000+0 的写出 10485760000字节(10 GB)已复制,18.5243 秒,566 MB/秒 #速度正常
切换至admin用户执行dd命令
[root@reddhat6_155_200 ~]# mv /root/bigfile1 /tmp/ [root@reddhat6_155_200 ~]# su - admin [admin@reddhat6_155_200 ~]$ dd if=/tmp/bigfile1 of=/dev/null
新开一个窗口,使用iotop命令监控
[admin@reddhat6_155_200 ~]$ dd if=/tmp/bigfile1 of=/dev/null 记录了210657+0 的读入 记录了210656+0 的写出 107855872字节(108 MB)已复制,107.986 秒,999 kB/秒 #注意此处的速率 时间是由于我提早中断了程序
咱们发现,不管怎样,IO读取不会大于1M
1 磁盘IO调度算法必须为cfq 2 测试前须要先清空磁盘缓存 3 不要使用SSD硬盘 4 读取速率注意SCSI物理硬盘盘符会随机更改
[root@reddhat6_155_200 ~]# vim /etc/cgconfig.conf mount { cpuset = /cgroup/cpuset; # cpu = /cgroup/cpu; #以CPU内存为例,注释cpu、memory字段 cpuacct = /cgroup/cpuacct; # memory = /cgroup/memory; cpu = /cgroup/cpumem; #新添加cpu、memory字段将其路径指向同一路径 memory = /cgroup/cpumem; devices = /cgroup/devices; freezer = /cgroup/freezer; net_cls = /cgroup/net_cls; blkio = /cgroup/blkio; }
[root@reddhat6_155_200 ~]# /etc/init.d/cgconfig restart Stopping cgconfig service: [肯定] Starting cgconfig service: [肯定]
[root@reddhat6_155_200 ~]# ll /cgroup/ 总用量 8 drwxr-xr-x. 2 root root 0 2019-09-07 15:07 blkio drwxr-xr-x. 2 root root 4096 2019-08-30 17:24 cpu drwxr-xr-x. 2 root root 0 2019-09-07 15:07 cpuacct drwxr-xr-x. 2 root root 0 2019-09-07 15:07 cpumem #咱们自定义的 drwxr-xr-x. 2 root root 0 2019-09-07 15:07 cpuset drwxr-xr-x. 2 root root 0 2019-09-07 15:07 devices drwxr-xr-x. 3 root root 0 2019-09-07 15:07 freezer drwxr-xr-x. 2 root root 4096 2019-08-30 17:24 memory drwxr-xr-x. 2 root root 0 2019-09-07 15:07 net_cls [root@reddhat6_155_200 ~]# ll /cgroup/cpu #原先的cpu及memory已经失效了 总用量 0 [root@reddhat6_155_200 ~]# ll /cgroup/memory/ 总用量 0 [root@reddhat6_155_200 ~]# ll /cgroup/cpumem/ #全部mem和cpu配置都在cpumem目录下 总用量 0
--w--w--w-. 1 root root 0 2019-09-07 15:07 cgroup.event_control -rw-r--r--. 1 root root 0 2019-09-07 15:07 cgroup.procs -rw-r--r--. 1 root root 0 2019-09-07 15:07 cpu.cfs_period_us -rw-r--r--. 1 root root 0 2019-09-07 15:07 cpu.cfs_quota_us -rw-r--r--. 1 root root 0 2019-09-07 15:07 cpu.rt_period_us -rw-r--r--. 1 root root 0 2019-09-07 15:07 cpu.rt_runtime_us -rw-r--r--. 1 root root 0 2019-09-07 15:07 cpu.shares -r--r--r--. 1 root root 0 2019-09-07 15:07 cpu.stat -rw-r--r--. 1 root root 0 2019-09-07 15:07 memory.failcnt --w-------. 1 root root 0 2019-09-07 15:07 memory.force_empty ......