CentOS7下CGroups最佳实践

 2017年8月21日 15:46   Nick王   运维  云计算    0 评论   1134 浏览 


实验环境:CentOS 7.3


cgroups是什么

cgroups全称为control groups,包含在Linux 内核中,顾名思义就是把任务放到一个组里面统一控制。官方定义如下:

cgroups是Linux内核提供的一种机制,这种机制可以根据需求把一系列系统任务以及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统管理提供一个统一的框架。

通俗的讲,cgroups可以限制、记录任务组所使用的物理资源(包括CPU、Memory、IO等),为容器实现虚拟化提供了基本的保证,是构建Docker等一系列虚拟化管理工具的基石。

对开发者来说,cgroups有如下四个有趣的特点:

  • cgroups的API以一个伪文件系统的方式实现,也就是说用户可以通过文件操作实现cgroups的组织与管理。

  • cgroups的组织管理操作单元可以细粒度到线程级别,用户态代码也可以针对系统分配的资源创建和销毁cgroups,从而实现资源再分配和管理。

  • 所有资源管理的功能都以“subsystem(子系统)”的方式实现,接口统一。

  • 子进程创建之初与其父进程处于同一个cgroups的控制组。

本质上来说,cgroups是内核附加在程序上的一系列钩子(hooks),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。

cgroups的作用

实现cgroups的主要目的是为不同用户层面的资源管理,提供一个统一化的接口。从单个任务的资源控制到操作系统层面的虚拟化,cgroups提供了四个功能:

  • 资源限制:cgroups可以对任务使用的资源总额进行限制。如设定应用程序运行时使用内存的上限,一旦超过配额就发出OOM的提示。

  • 优先级分配:通过分配的CPU时间片数量以及磁盘IO带宽大小,实际上就相当于控制了任务运行的优先级。

  • 资源统计:cgroups可以统计系统的资源使用量,比如CPU使用的时长、内存使用量等。

  • 任务控制:cgroups可以对任务执行挂起,恢复操作。

cgroups术语表

  • task(任务): 任务表示系统的一个进程或者是线程。

  • cgroup(控制组,任务组):在cgroups中的资源控制都是以cgroup为单位实现的。cgroup表示按照某种资源控制标准划分的任务组,包含一个或者多个子系统。一个任务可以加入到某个cgroup,也可以从某个cgroup迁移到另外一个cgroup。

  • subsystem(子系统):cgroups中的子系统就是一个资源调度控制器。比如CPU子系统可以控制CPU时间分配,内存子系统可以控制内存使用量。

  • hierarchy(层级):层级由一系列控制组(cgroup)已一个树状结构排列而成,每个层级通过绑定对应的子系统进行资源控制。层级中的cgroup节点也可以包含零或者多个子节点,子节点继承父节点挂载的子系统。整个操作系统可以有多个层级。

如下是CentOS 7.0 CGroups默认的层级:

# systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
├─user.slice
│ └─user-0.slice
│   └─session-343.scope
│     ├─22076 sshd: root@pts/0
│     ├─22078 -bash
│     ├─22100 systemd-cgls
│     └─22101 less
└─system.slice
  ├─aliyun.service
  │ └─6858 /usr/sbin/aliyun-service
  ├─sshd.service
  │ └─4056 /usr/sbin/sshd -D
  ├─aegis.service
  │ ├─1021 /usr/local/aegis/aegis_update/AliYunDunUpdate
  │ └─1511 /usr/local/aegis/aegis_client/aegis_10_25/AliYunDun
……省略……


组织结构与基本规则

系统中的多个cgroup的构成类似Linux 系统中的进程树的树状结构,直接点从父节点继承属性。

不同之处,在于系统的多个cgroup构成的层级并非是单根结构,而是允许多个存在的。如果说进程树是一棵树的话,那么系统中的多个cgroup则是由多个层级构成的森林。

基本规则

  1. 同一个层级可以附加一个或者多个子系统。比如可以同时附加CPU子系统和内存系统到同一个层级。

  2. 一个已经附加在某个层级上的子系统不能附加到其他含有别的子系统的层级上。 一个子系统可以附加到多个层级,并且目标子系统只能有一个唯一的子系统。比如层级A附加了CPU子系统,层级B附加了内存子系统;那么CPU子系统就不能再继续附加到层级B上;如果层级B没有附加任何子系统,那么CPU子系统是可以附加到层级B上的。

  3. 一个任务不能属于同一个层级的不同cgroup,一个任务属于不同层级的多个cgroup中。如果一个任务添加到同一个层级的另一个cgroup中,则会将它从之前的cgroup中移除,也就是说一个任务只能在同一个层级的某个cgroup中。比如一个httpd的任务被加入了层级A的/cg1中,如果将httpd任务加入层级A的/cg2中,那么最终httpd任务会在/cg2中;httpd不能同时在层级A中的/cg1和/cg2同时存在;但是httpd任何可以加入到层级B的/cg1中。

  4. fork/clone出来的子任务在初始状态的时候与父任务处在同一个层级的同一个cgroup中,但是随后,可以将子任务加入到同一个层级的其他cgroup中。比如,httpd任务在层级A的/cg1中,当httpd任务刚fork出一个子httpd的时候,两者都会在/cg1中。但是随后,可以将子httpd移动到层级A的/cg2中。因为父子任务已经独立了。

子系统

子系统实际上就是cgroups的资源控制系统,每种子系统独立的控制一种资源。

资源管控器(也称为 cgroup 子系统)代表一种单一资源:如 CPU 时间或者内存。Linux kernel 提供一系列资源管控器,由 systemd 自动挂载。如需参考目前已挂载的资源管控器列表,请参见 /proc/cgroups,或使用 lssubsys 监控工具。

# cat /proc/cgroups
#subsys_name    hierarchy   num_cgroups enabled
cpuset  3   1   1
cpu 2   1   1
cpuacct 2   1   1
memory  11  1   1
devices 10  18  1
freezer 7   1   1
net_cls 5   1   1
blkio   9   1   1
perf_event  4   1   1
hugetlb 8   1   1
pids    6   1   1
net_prio    5   1   1

CentOS 7 中可用的管控器:

  1. cpu:使用CPU调度程序控制cgroup中的任务对CPU的使用。它与 cpuacct 管控器一起挂载在同一mount 上。

  2. cpuacct:自动生成cgroup中任务对CPU资源使用情况的报告。它与 cpu 管控器一起挂载在同一 mount 上。

  3. cpuset:可以为cgroup中的任务分配独立的CPU和内存。

  4. devices:可以开启或者关闭cgroup中的任务对设备的访问。

  5. blkio:可以为块设备设定输入/输出限制。

  6. freezer:可以挂起或者回复cgroup中的任务。

  7. memory:可以设定cgroup中的任务对内存使用量的限制,并生成这些任务对内存资源使用情况的报告。

  8. perf_event:使用后使cgroup中的任务可以进行统一的性能测试。允许使用 perf 工具来监控 cgroup。

  9. net_cls:使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc命令)识别从具体 cgroup 中生成的数据包。

  10. hugetlb:允许使用大篇幅的虚拟内存页,并且给这些内存页强制设定可用资源量。主要针对于HugeTLB系统进行限制,这是一个大页文件系统。


systemd-cgls 指令给 cgroup 层级提供了静态数据快照。要查看按资源使用量(CPU、内存和 IO)排序的、正在运行的 cgroup 动态描述请使用systemd-cgtop:

# systemd-cgtop    按h 查看帮助文档
Path                                                                                     Tasks   %CPU   Memory  Input/s Output/s

/                                                                                           93    2.4    11.1G        -        -
/user.slice                                                                                 20    2.0     5.1G        -        -
/system.slice                                                                                -    0.3     4.0G        -        -
/system.slice/docker.service                                                                 8    0.1     3.7G        -        -
/docker                                                                                      -    0.1     1.8G        -        -
/system.slice/aegis.service                                                                  2    0.1   119.4M        -        -
/docker/d74b44548707db6cbe1cadd225506d3e84a26500f2fda6550c988f91357e5f53                     3    0.1    18.4M        -        -
/docker/90fa9895f814ac36b00e4971a4497e318033d1a5c10d0e7d95c7412288de8b5e                     4    0.0   619.4M        -        -
/system.slice/aliyun.service                                                                 1    0.0     1.2M        -        -
/system.slice/tuned.service                                                                  1    0.0    12.4M        -        -
/system.slice/httpd.service                                                                  6    0.0     2.9M        -        -
/system.slice/atd.service                                                                    1      -   260.0K        -        -
/system.slice/auditd.service                                                                 1      -    20.6M        -        -
/system.slice/crond.service                                                                  1      -   748.0K        -        -
/system.slice/dbus.service                                                                   1      -     1.1M        -        -
/system.slice/dev-hugepages.mount                                                            -      -   388.0K        -        -
/system.slice/dev-mqueue.mount                                                               -      -   108.0K        -        -
/system.slice/irqbalance.service                                                             1      -   460.0K        -        -
/system.slice/ntpd.service                                                                   1      -     1.5M        -        -
/system.slice/polkit.service                                                                 1      -    14.5M        -        -
……省略

使用CGroups

在CentOS 7.x 系统中可以使用如下命令安装用户态管理工具:

# yum install libcgroup-tools -y

安装了如下内容:

# rpm -ql libcgroup-tools
/etc/cgconfig.conf
/etc/cgconfig.d
/etc/cgrules.conf
/etc/cgsnapshot_blacklist.conf
/etc/sysconfig/cgred
/usr/bin/cgclassify
/usr/bin/cgcreate
/usr/bin/cgdelete
/usr/bin/cgexec
/usr/bin/cgget
/usr/bin/cgset
/usr/bin/cgsnapshot
/usr/bin/lscgroup
/usr/bin/lssubsys
/usr/lib/systemd/system/cgconfig.service
/usr/lib/systemd/system/cgred.service
/usr/sbin/cgclear
/usr/sbin/cgconfigparser
/usr/sbin/cgrulesengd
……
# rpm -ql libcgroup
/usr/lib64/libcgroup.so.1
/usr/lib64/libcgroup.so.1.0.41


列出当前的子系统

# lssubsys
cpuset
cpu,cpuacct
memory
devices
freezer
net_cls,net_prio
blkio
perf_event
hugetlb
pids

查看内存子系统挂载的层级

# lssubsys -m memory
memory /sys/fs/cgroup/memory


显示子系统mount目录

可以使用lssubsys命令列出系统中的所有层级,可用子系统以及当前的挂载点

# lssubsys -aim
cpuset /sys/fs/cgroup/cpuset   这里表示/sys/fs/cgroup/cpuset 层级上附加了cpuset子系统
cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb
pids /sys/fs/cgroup/pids

显示所有资源组

# lscgroup
cpu,cpuacct:/
net_cls,net_prio:/
blkio:/
perf_event:/
cpuset:/
memory:/
pids:/
hugetlb:/
freezer:/
devices:/

使用umount卸载层级,并重新挂载到另外的层级

# umount /sys/fs/cgroup/cpuset    ## 通过卸载挂载点,删除层级

# lssubsys -aim    ## 查看所有子系统
cpuset
cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb
pids /sys/fs/cgroup/pids

# mount -t cgroup -o cpuset cpuset /cgroups/cpuset/   ## mount -t cgroup -o subsystems name 挂载点   其中name表示层级名称

# ls /cgroups/cpuset/
cgroup.clone_children  cpuset.cpu_exclusive  cpuset.memory_migrate           cpuset.memory_spread_slab        notify_on_release
cgroup.event_control   cpuset.cpus           cpuset.memory_pressure          cpuset.mems                      release_agent
cgroup.procs           cpuset.mem_exclusive  cpuset.memory_pressure_enabled  cpuset.sched_load_balance        tasks
cgroup.sane_behavior   cpuset.mem_hardwall   cpuset.memory_spread_page       cpuset.sched_relax_domain_level

# lssubsys -aim
cpuset /cgroups/cpuset
cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb
pids /sys/fs/cgroup/pids

查看mount支持的文件系统类型

# cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   ramfs
nodev   bdev
nodev   proc
nodev   cgroup
nodev   cpuset
nodev   tmpfs
nodev   devtmpfs
nodev   debugfs
nodev   securityfs
nodev   sockfs
nodev   pipefs
nodev   anon_inodefs
nodev   configfs
nodev   devpts
nodev   hugetlbfs
nodev   autofs
nodev   pstore
nodev   mqueue
    ext3
    ext2    
    ext4

清除整个cgroups文件系统

使用不带任何参数的cgclear命令可以清除整个cgroups文件系统

# cgclear

# lssubsys -aimcpuset
cpu
cpuacct
memory
devices
freezer
net_cls
blkio
perf_event
hugetlb
pids
net_prio

一次完整实践过程

创建一个临时的文件系统

# mkdir /cgroup


# mount -t tmpfs my-cgroups /cgroup    ## my-cgroups 是显示的名字 可以随便定义  ,  这里使用临时文件系统


# df -Th /cgroup
Filesystem     Type   Size  Used Avail Use% Mounted on
my-cgroups     tmpfs   16G     0   16G   0% /cgroup

挂载子系统到相应的层级

# mkdir /cgroup/cg1


# mount -t cgroup -o cpu,memory cpu_and_mem /cgroup/cg1  ## -o 指定的是子系统名称; cpu_and_mem表示层级名称; 最后的是挂载点


# lssubsys -aim
cpuset
cpuacct
devices
freezer
net_cls
blkio
perf_event
hugetlb
pids
net_prio
cpu,memory /cgroup/cg1


# ls /cgroup/cg1/
cgroup.clone_children  memory.failcnt                      memory.kmem.usage_in_bytes       memory.pressure_level
cgroup.event_control   memory.force_empty                  memory.limit_in_bytes            memory.soft_limit_in_bytes
cgroup.procs           memory.kmem.failcnt                 memory.max_usage_in_bytes        memory.stat
cgroup.sane_behavior   memory.kmem.limit_in_bytes          memory.memsw.failcnt             memory.swappiness
cpu.cfs_period_us      memory.kmem.max_usage_in_bytes      memory.memsw.limit_in_bytes      memory.usage_in_bytes
cpu.cfs_quota_us       memory.kmem.slabinfo                memory.memsw.max_usage_in_bytes  memory.use_hierarchy
cpu.rt_period_us       memory.kmem.tcp.failcnt             memory.memsw.usage_in_bytes      notify_on_release
cpu.rt_runtime_us      memory.kmem.tcp.limit_in_bytes      memory.move_charge_at_immigrate  release_agent
cpu.shares             memory.kmem.tcp.max_usage_in_bytes  memory.numa_stat                 tasks
cpu.stat               memory.kmem.tcp.usage_in_bytes      memory.oom_control


# mount |grep cpu_and_mem
cpu_and_mem on /cgroup/cg1 type cgroup (rw,relatime,memory,cpu)

重新附加子系统

# lssubsys -aim
cpuset
cpuacct
devices
freezer
net_cls
blkio
perf_event
hugetlb
pids
net_prio
cpu,memory /cgroup/cg1


# mount -t cgroup -o remount,cpu,cpuset,memory cpu_and_mem /cgroup/cg1   ## 注意remount选项


# lssubsys -aim
cpuacct
devices
freezer
net_cls
blkio
perf_event
hugetlb
pids
net_prio
cpuset,cpu,memory /cgroup/cg1


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

使用cgcreate创建cgroups控制组

# cgcreate -t root:root -a root:root -g cpu,cpuset,memory:/cg1-1


# ls /cgroup/cg1/cg1-1/
cgroup.clone_children  cpuset.memory_pressure           memory.kmem.max_usage_in_bytes      memory.memsw.usage_in_bytes
cgroup.event_control   cpuset.memory_spread_page        memory.kmem.slabinfo                memory.move_charge_at_immigrate
cgroup.procs           cpuset.memory_spread_slab        memory.kmem.tcp.failcnt             memory.numa_stat
cpu.cfs_period_us      cpuset.mems                      memory.kmem.tcp.limit_in_bytes      memory.oom_control
cpu.cfs_quota_us       cpuset.sched_load_balance        memory.kmem.tcp.max_usage_in_bytes  memory.pressure_level
cpu.rt_period_us       cpuset.sched_relax_domain_level  memory.kmem.tcp.usage_in_bytes      memory.soft_limit_in_bytes
cpu.rt_runtime_us      cpu.shares                       memory.kmem.usage_in_bytes          memory.stat
cpuset.cpu_exclusive   cpu.stat                         memory.limit_in_bytes               memory.swappiness
cpuset.cpus            memory.failcnt                   memory.max_usage_in_bytes           memory.usage_in_bytes
cpuset.mem_exclusive   memory.force_empty               memory.memsw.failcnt                memory.use_hierarchy
cpuset.mem_hardwall    memory.kmem.failcnt              memory.memsw.limit_in_bytes         notify_on_release
cpuset.memory_migrate  memory.kmem.limit_in_bytes       memory.memsw.max_usage_in_bytes     tasks

说明:

  • 选项t表示指定用户可以在该CGroups中添加进程

  • 选项a表示指定用户可以修改这个CGroups总进程对资源的访问

  • 选项g表示指定层级,格式关联的用逗号分开的subsystems列表

查看控制组

# lscgroup
cpuset,cpu,memory:/
cpuset,cpu,memory:/cg1-1

给控制组设定参数

# cgset -r cpuset.cpus=0-1 cpuset,cpu,memory:/cg1-1


# cat /cgroup/cg1/cg1-1/cpuset.cpus
0-1

# echo 0-2 > /cgroup/cg1/cg1-1/cpuset.cpus


# cat /cgroup/cg1/cg1-1/cpuset.cpus
0-2

除了上述两种方式,还可以使用cgset --copy-from 群组1 群组2的方式来实现。

移动某个进程到控制群组中

# yum install httpd -y

# systemctl start httpd


# ps -ef|grep httpd
root      2956     1  0 23:16 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2957  2956  0 23:16 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2958  2956  0 23:16 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2959  2956  0 23:16 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2960  2956  0 23:16 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2961  2956  0 23:16 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND


# cat /cgroup/cg1/cg1-1/tasks


# echo 0 > /cgroup/cg1/cg1-1/cpuset.mems  ## 注意这里一定要设置,因为上面只设置了使用的CPU核心, 并没有给内存, 必须两者都给才能添加task

# echo 2956 >> /cgroup/cg1/cg1-1/tasks


# cgclassify -g cpuset,cpu,memory:/cg1-1 2957


# cgclassify -g cpuset,cpu,memory:/cg1-1 2958


# cgclassify -g cpuset,cpu,memory:/cg1-1 2959


# cat /cgroup/cg1/cg1-1/tasks2956295729582959


# ps -eo psr,cgroup,pid|grep -E "2956|2957|2958|2959"
  0 14:cpuset,memory,cpu:/cg1-1  2956
  1 14:cpuset,memory,cpu:/cg1-1  2957
  3 14:cpuset,memory,cpu:/cg1-1  2958
  1 14:cpuset,memory,cpu:/cg1-1  2959
  

# cat /proc/2956/cgroup
14:cpuset,memory,cpu:/cg1-1
1:name=systemd:/system.slice/httpd.service

获取控制组附加的某个子系统的具体参数:

# cgget -g cpuset /cg1-1
/cg1-1:
cpuset.memory_spread_slab: 0
cpuset.memory_spread_page: 0
cpuset.memory_pressure: 0
cpuset.memory_migrate: 0
cpuset.sched_relax_domain_level: -1
cpuset.sched_load_balance: 1
cpuset.mem_hardwall: 0
cpuset.mem_exclusive: 0
cpuset.cpu_exclusive: 0
cpuset.mems: 0
cpuset.cpus: 0-2


# cgget -r cpuset.cpus /cg1-1  ## 指定获取参数
/cg1-1:
cpuset.cpus: 0-2


在控制群组中启动一个进程

# cgexec -g cpuset,cpu,memory:/cg1-1 lynx http://www.aliyun.com


清除所有cgroup

# cgclear


# lscgroup
cgroups can't be listed: Cgroup is not mounted


# lssubsys -aim
cpuset
cpu
cpuacct
memory
devices
freezer
net_cls
blkio
perf_event
hugetlb
pids
net_prio


权限管理

与文件的权限管理类似, 通过chown命令就可以对cgroup文件系统进行权限管理。

关于cgroups参数设置的文档

kernel-doc 数据包给所有资源管控器提供了详细文档。

# yum install kernel-doc -y

安装完成后,下列文件会出现在 /usr/share/doc/kernel-doc-<kernel_version>/Documentation/cgroups/ 目录中:

# less /usr/share/doc/kernel-doc-3.10.0/Documentation/cgroups/cpusets.txt

  • blkio 子系统 —— blkio-controller.txt

  • cpuacct 子系统 —— cpuacct.txt

  • cpuset 子系统 ——cpusets.txt

  • devices 子系统 —— devices.txt

  • freezer 子系统 —— freezer-subsystem.txt

  • memory 子系统 —— memory.txt

  • net_cls 子系统 — net_cls.txt

Docker 是如何使用CGroups的

在Docker的实现中,Docker daemon 会在单独挂载了每一个子系统的控制组目录(比如 /sys/fs/cgroup/cpu)下创建一个名为docker的控制组;然后在docker控制组里面,再为每个容器创建一个以容器ID为名称的容器控制组。这个容器里面所有进程的进程号都会写到该控制组的tasks中,并且会在控制文件(比如 cpu.cfs_quota_us)中写入 预设值。

CentOS 7上的默认层级结构:

# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)


Docker组的层级结构如下:

# tree /sys/fs/cgroup/cpu/docker/
/sys/fs/cgroup/cpu/docker/
├── 90fa9895f814ac36b00e4971a4497e318033d1a5c10d0e7d95c7412288de8b5e
│   ├── cgroup.clone_children
│   ├── cgroup.event_control
│   ├── cgroup.procs
│   ├── cpuacct.stat
│   ├── cpuacct.usage
│   ├── cpuacct.usage_percpu
│   ├── cpu.cfs_period_us
│   ├── cpu.cfs_quota_us
│   ├── cpu.rt_period_us
│   ├── cpu.rt_runtime_us
│   ├── cpu.shares
│   ├── cpu.stat
│   ├── notify_on_release
│   └── tasks
├── cgroup.clone_children
├── cgroup.event_control
├── cgroup.procs
├── cpuacct.stat
├── cpuacct.usage
├── cpuacct.usage_percpu
├── cpu.cfs_period_us
├── cpu.cfs_quota_us
├── cpu.rt_period_us
├── cpu.rt_runtime_us
├── cpu.shares
├── cpu.stat
├── d74b44548707db6cbe1cadd225506d3e84a26500f2fda6550c988f91357e5f53
│   ├── cgroup.clone_children
│   ├── cgroup.event_control
│   ├── cgroup.procs
│   ├── cpuacct.stat
│   ├── cpuacct.usage
│   ├── cpuacct.usage_percpu
│   ├── cpu.cfs_period_us
│   ├── cpu.cfs_quota_us
│   ├── cpu.rt_period_us
│   ├── cpu.rt_runtime_us
│   ├── cpu.shares
│   ├── cpu.stat
│   ├── notify_on_release
│   └── tasks
├── notify_on_release
└── tasks2 directories, 42 files

Docker 在使用cgroup时的注意事项

在实际使用过程中, Docker需要通过挂载cgroup文件系统新建一个层级结构,挂载时指定要绑定的子系统。把cgroup文件系统挂载上之后,就可以像操作文件一样对cgroup的层级进行浏览和操作管理(包括权限管理、子文件管理等。)除了cgroup文件系统以外,内核没有为cgroups的访问和操作添加任何系统调用。

当一个顶层的cgroup文件系统被卸载的时候,如果其中创建过深层次的后代cgroup目录,那么就算上层的cgroup卸载了,层级也是激活的状态,其后台cgroup中的配置依旧有效。只有递归式的卸载层级中的所有cgroup,那么层级才会被真正删除。

在创建的层级中创建文件夹,就类似fork了一个后代cgroup,后代cgroup中默认继承原有cgroup中的配置属性,但是可以根据需求对配置参数进行调整。这样就把一个大的cgroup系统分割成一个个嵌套的、可动态变化的"软分区"。

# pwd
/sys/fs/cgroup/cpu


# mkdir test  ## 创建目录,自动fork了一个后代cgroup

# ls
cgroup.clone_children  cgroup.sane_behavior  cpuacct.usage_percpu  cpu.rt_period_us   cpu.stat           tasks
cgroup.event_control   cpuacct.stat          cpu.cfs_period_us     cpu.rt_runtime_us  notify_on_release  testcgroup.procs           cpuacct.usage         cpu.cfs_quota_us      cpu.shares         release_agent

# ls test/   ## 已经有参数配置了
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks

# lscgroup   ## 查看所有的cgroup
devices:/
perf_event:/
net_cls,net_prio:/
pids:/
cpu,cpuacct:/
cpu,cpuacct:/test    ## 看这里
blkio:/
hugetlb:/
freezer:/
cpuset:/
memory:/

# rmdir test/    ## 删除cgroup,  也可以使用cgdelete


参考文档:

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Resource_Management_Guide/index.html



如无特殊说明,文章均为本站原创,转载请注明出处