RHEL7 Cgroups概述
默认的Cgroup层次结构
默认情况下systemd自动创建一个slice(片),scope(范围)和service(服务)单元来提供cgroup树的统一结构。使用systemctl命令,可以通过创建定制的slice来修改这个层次结构。并且,systemd为重要的内核资源控制器在/sys/fs/cgroup/目录下自动挂载层次结构。
警告
通过libcgroup软件包提供的cgconfig工具可以挂载和处理控制器的层次结构,但不被systemd所支持(尤其是net-prio控制器)。绝对不要使用libcgroup工具来修改通过systemd所挂载的默认层次结构,因为这样会导致不可预知的错误。libcgroup软件包将在未来的Red Hat Enterprise Linux版本中移除。
Systemd单元类型
systemd是Red Hat Enterprise Linux 7开始取代init的服务管理系统,本段落内容适用于RHEL 7。
所有运行在系统(RHEL 7)中的进程都是systemd init进程的子进程。systemd提供了三种单元类型用于资源控制目的:
Service服务 - 一个进程或者一组进程,由systemd基于单元(unit)配置文件启动。服务包装了特定的进程,这样它们可以作为一个整体进行启动或停止。服务被命名成如下方式:
name.serviceScope范围 - 一组外部创建的进程。scope包装了通过fork()功能启动和停止的进程,然后在运行时由systemd注册进程。例如,用户会话,容器和虚拟机就被视为scope。scope被命名成如下方式:
name.scopeslice分片 - 使用unit层次化组织的组。slice不包含进程,它是由scope和service组成的层次结构。活跃的进程则包含在scope或service中。在层次结构树中,每个slice单元的命名都对应了层级结构中指向目标的路径。符号-就表示路径组件特征。例如,如果一个slice类似如下:
parent-name.slice则表示这个parent-name.slice是parent.slice的subslice,这个slice也可以有自己的subslice,例如parent-name-name2.slice,依次类推。这里的根slice是-.slice。
service,scope和slice单元在cgroup树中直接被映射到对象。当这些单元被激活,每个单元都各自直接映射到单元名字对应的cgroup路径。例如位于test-waldo.slice中的ex.service被映射到cgroup的test.slice/test-waldo.slice/ex.service/。
service,scope和slice可以由系统管理员手工创建或者由程序动态创建。默认情况,操作系统定义了一组运行系统所必须的服务。即,默认有4个slice:
-.slice- 根slicesystem.slice- 所有系统服务的默认存放位置user.slice- 所有用户会话的默认存放位置machine.slice- 所有虚拟机和容器的默认存放位置
注意,所有用户会话被自动放到一个独立的scope单元,虚拟机和容器进程也是这样处理的。而且,所有用户被指派到一个默认的subslice。在这个默认配置中,系统管理员可以定义一个新的slice并指定service和scope到这个slice中。
以下是systemd-cgls命令的输出案例:
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
├─user.slice
│ └─user-1000.slice
│ └─session-2.scope
│ ├─2069 sshd: vagrant [priv]
│ ├─2072 sshd: vagrant@pts/0
│ ├─2073 -bash
│ ├─2253 systemd-cgls
│ └─2254 systemd-cgls
└─system.slice
├─postfix.service
│ ├─1200 /usr/libexec/postfix/master -w
│ ├─1216 qmgr -l -t unix -u
│ └─2250 pickup -l -t unix -u
├─sshd.service
│ └─888 /usr/sbin/sshd -D
...上述案例可以看到service和scope包含进程,并且service和scope又被包含在slice中,而slice是不直接包含进程的。唯一的例外是PID为1的进程,位于特殊的systemd.slice中。还要注意,-.slice并没有显示在输出中,这是因为它表示了整个cgroup树。
service和slice单元可以通过单元文件配置或者动态通过调用PID 1的API来创建。scope单元则只能使用单元配置文件的方法来创建。通过API调用方法动态创建的单元是临时的并且只在运行期间存在。这些短暂存在的单元在单元结束时、禁用时或系统重启时自动释放。
Linux内核中的资源控制器
资源控制器(resource controller),也称为cgroup子系统(cgroup subsystem),相当于一个单一资源,例如CPU时间或内存。Linux内核提供了一系列的资源控制器,它们都通过systemd自动挂载。
在/proc/cgroups中列出了当前挂载的resource controller列表
cat /proc/cgroups输出内容
#subsys_name hierarchy num_cgroups enabled
cpuset 7 1 1
cpu 5 1 1
cpuacct 5 1 1
memory 8 1 1
devices 10 1 1
freezer 6 1 1
net_cls 3 1 1
blkio 2 1 1
perf_event 4 1 1
hugetlb 9 1 1也可以通过lssubsys(该命令属于libcgroup-tools软件包),其中-i参数表示层次结构,-m参数表示输出挂载
lssubsys -i输出
cpuset 7
cpu,cpuacct 5
memory 8
devices 10
freezer 6
net_cls 3
blkio 2
perf_event 4
hugetlb 9lssubsys -mcpuset /sys/fs/cgroup/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 /sys/fs/cgroup/net_cls
blkio /sys/fs/cgroup/blkio
perf_event /sys/fs/cgroup/perf_event
hugetlb /sys/fs/cgroup/hugetlb在RHEL 7中可用的资源控制器:
blkio- 设置访问块设备的I/O存取限制cpu- 设置CPU调度算法提供cgroup调度任务访问CPU。这个挂载是和cpuacct控制器同时挂载的cpuacct- 通过使用cgroup的任务创建CPU资源的自动报告。这个挂载是和cpu控制器同时挂载的cpuset- 在多核系统中指定独立的CPU和内存节点给cgroup的任务devices- 允许或拒绝cgroup中的任务访问设备freezer- 挂起或继续cgroup重大任务memory- 通过cgroup中的任务设置内存限制,并通过其他任务来自动创建内存资源的报告net_cls- 通过分类标记(classid)来标记网络数据包,这样Linux流量控制器(tc命令)从参与的cgroup任务中标记数据包。perf_event- 通过perf工具激活监控cgroupshugetlb- 允许使用大的虚拟内存也,并强化资源限制在这些内存页
Linux内核针对可以通过systemd配置的资源控制来提供广泛的性能调优参数。
相关信息资源
cgroup相关的systemd文档
以下手册页(man)包含了systemd下的cgroup通用信息
systemd.resource-control- 描述通过system单元共享的资源控制配置选项systemd.unit- 描述所有单元配置文件的常用项systemd.slice- 提供.slice单元的通用信息systemd.scope- 提供.scope单元的通用信息systemd.service- 提供.service单元的通用信息
控制器相关内核文档
内核文档软件包提供了详细的有关所有资源控制器的文档。这个软件包包含了可选的订阅通道。
yum install kernel-doc安装完成后,相关文件位于 /usr/share/doc/kernel-doc-<kernel_version>/Documentation/cgroups/目录。
在线文档
Red Hat Enterprise Linux 7 System Administrators Guide - 详细解释了systemd概念和相关的服务管理方法
The D-Bus API of systemd - 有关使用D-Bus API命令和
systemd交互的参考手册
参考
Last updated
Was this helpful?