如何在CentOS6上使用cgroups限制资源
状态:已弃用
本文介绍了不再受支持的 CentOS 版本。 如果您目前正在运行运行 CentOS 6 的服务器,我们强烈建议您升级或迁移到受支持的 CentOS 版本。
原因:CentOS 6 已于 2020 年 11 月 30 日结束生命周期 (EOL) ,不再接收安全补丁或更新。 因此,不再维护本指南。
请参阅:本指南可能仍可用作参考,但可能不适用于其他 CentOS 版本。 如果可用,我们强烈建议使用为您正在使用的 CentOS 版本编写的指南。
介绍
控制组或 cgroups 是 CentOS 6 中引入的内核功能,用于提供一种限制进程访问系统资源的新方法。 您可以创建自己的 cgroups、监控您配置的 cgroups、拒绝 cgroups 访问某些资源,甚至可以在正在运行的系统上动态重新配置您的 cgroups。
在本教程中,我们将了解如何限制进程的 CPU、内存和磁盘 I/O。 为此,我们将首先创建一些控制组,向它们添加流程,并查看它们的执行情况。
先决条件
在开始学习本教程之前,您应该在 CentOS 6 Droplet 上拥有一个具有 sudo 设置的非 root 用户。 要设置这种类型的用户,请按照我们的 Initial Server Setup with CentOS 6 教程进行操作。 所有命令都将以该用户身份运行。
第 1 步 — 安装
在本节中,我们将安装 cgroup 运行所需的软件包。
可以使用 shell 命令和实用程序来操作控制组及其相关的子系统。 然而,使用 cgroups 最简单的方法是安装 libcgroup
包。 libcgroup
软件包提供了与 cgroups 相关的命令行实用程序、配置文件和手册页。 CentOS 6 服务器上默认不安装此软件包。 要安装它,请运行以下命令:
sudo yum install libcgroup
第 2 步 — 启动服务
cgconfig
(控制组配置)服务用于创建 cgroup 和管理子系统。 它可以配置为在引导时启动并重新建立预定义的 cgroup,从而使它们在重新引导后保持不变。 CentOS 6默认不启动cgconfig
服务,让我们启动它:
sudo service cgconfig start
启动 cgconfig
服务会创建一个安装在 /cgroup
的虚拟文件系统,其中包含所有子系统。 让我们验证一下:
sudo ls /cgroup
此命令应显示以下子系统:
blkio cpu cpuacct cpuset devices freezer memory net_cls
您还可以运行“lscgroup”命令来验证:
sudo lscgroup
您将看到布局略有不同的子系统:
cpuset:/ cpu:/ cpuacct:/ memory:/ devices:/ freezer:/ net_cls:/ blkio:/
系统资源
系统资源称为子系统,每个子系统都有几个可以赋值的参数。 CentOS 6 提供了十个 cgroup 子系统:
- blkio — 该子系统设置对块设备的输入/输出访问限制,例如物理驱动器(磁盘、固态、USB 等)。
- cpu — 此子系统设置可用 CPU 时间的限制
- cpuacct — 该子系统生成关于 cgroup 中任务使用的 CPU 资源的自动报告
- cpuset — 该子系统将单个 CPU(在多核系统上)和内存节点分配给 cgroup 中的任务
- devices — 此子系统允许或拒绝 cgroup 中的任务访问设备
- freezer — 该子系统暂停或恢复 cgroup 中的任务
- memory — 该子系统设置 cgroup 中任务使用的内存限制,并生成这些任务使用的内存资源的自动报告
- net_cls — 该子系统使用类标识符 (classid) 标记网络数据包,允许 Linux 流量控制器 (tc) 识别源自特定 cgroup 任务的数据包
- net_prio — 该子系统提供了一种动态设置每个网络接口的网络流量优先级的方法
- ns — 这是命名空间子系统
第 3 步 — 配置
在本节中,我们将创建示例 cgroup 并为这些 cgroup 设置一些资源限制。 cgroup 配置文件为 /etc/cgconfig.conf
。 根据配置文件的内容,cgconfig 可以创建层次结构,挂载必要的文件系统,创建 cgroup,并为每个 cgroup 设置子系统参数(资源限制)。
层次结构是一组排列在树中的 cgroup,这样系统中的每个任务都恰好位于层次结构中的一个 cgroup 中。 在默认的 CentOS 6 配置中,每个子系统都被放入其自己的层次结构中。
让我们首先创建几个名为limitcpu、limitmem、limitio 和browser 的cgroup。 /etc/cgconfig.conf
文件包含两种主要类型的条目 — mount
和 group
。 以 group
开头的行创建 cgroup 并设置子系统参数。 编辑文件 /etc/cgconfig.conf
并在底部添加以下 cgroup 条目:
/etc/cgconfig.conf
group limitcpu{ cpu { cpu.shares = 400; } } group limitmem{ memory { memory.limit_in_bytes = 512m; } } group limitio{ blkio { blkio.throttle.read_bps_device = "252:0 2097152"; } } group browsers{ cpu { cpu.shares = 200; } memory { memory.limit_in_bytes = 128m; } }
- 在
limitcpu
cgroup 中,我们将此 cgroup 中的进程可用的 cpu 份额限制为 400。cpu.shares
指定 cgroup 中任务可用的 CPU 时间的相对份额。 - 在
limitmem
cgroup 中,我们将 cgroup 进程可用的内存限制为 512MB。 - 在
limitio
cgroup 中,我们将磁盘读取吞吐量限制为 2MiB/s。 在这里,我们将读取 I/O 限制在主磁盘 /dev/vda,主要:次要编号为 252:0,并且 2MiB/s 转换为每秒字节数 (2x1024x1024=2097152)。 - 在
browsers
cgroup 中,我们将 cpu 共享限制为 200,可用内存限制为 128MB。
我们需要重启cgconfig
服务才能使/etc/cgconfig.conf
文件中的更改生效:
sudo service cgconfig restart
让我们启用 cgconfig
在系统启动时启动。 当您使用 chkconfig 启用该服务时,它会在启动时读取 cgroup 配置文件 /etc/cgconfig.conf
。 cgroups 在会话之间重新创建并保持持久性。
sudo chkconfig cgconfig on
接下来,验证我们配置的 cgroup 是否正确显示:
lscgroup
如果一切顺利,您应该看到:
cpuset:/ cpu:/ cpu:/browsers cpu:/limitcpu cpuacct:/ memory:/ memory:/browsers memory:/limitmem devices:/ freezer:/ net_cls:/ blkio:/ blkio:/limitio
我们的下一个目标是将我们希望为其限制资源的进程(任务)添加到我们之前创建的 cgroups。
Cgred
(控制组规则引擎守护程序)是一项根据 /etc/cgrules.conf
文件中设置的参数将任务移动到 cgroups 中的服务。 /etc/cgrules.conf
文件中的条目可以采用以下两种形式之一:
user subsystems control_group
或者
user:command subsystems control_group
user
指以“@”字符为前缀的用户名或组名。 subsystems
是指以逗号分隔的子系统名称列表。 control_group
代表cgroup的路径,command
代表进程名或进程的完整命令路径。 /etc/cgrules.conf
文件中的条目可以包含以下额外符号:
@
— 表示一个组而不是单个用户。 例如,@admin
表示 admin 组中的所有用户。*
— 代表“全部”。 例如,用户字段中的*
代表所有用户。%
— 表示与上一行中的项目相同的项目。
现在让我们添加我们希望限制的程序/进程。 编辑 /etc/cgrules.conf
并在底部添加以下内容:
/etc/cgrules.conf
*:firefox cpu,memory browsers/ *:hdparm blkio limitio/ sammy blkio limitio/ @admin:memhog memory limitmem/ *:cpuhog cpu limitcpu/
在以上几行中,我们设置了以下规则:
- 任何用户运行的 firefox 进程将被自动添加到
browsers
cgroup 中,并限制在 cpu 和 memory 子系统中。 - 任何用户运行的 hdparm 进程将被添加到
limitio
cgroup 中,并将根据该 cgroup 中指定的参数值限制在 blkio 子系统中。 - 用户 sammy 运行的所有进程都将被添加到
limitio
cgroup 中,并限制在 blkio 子系统中。 admin
组中的任何人运行的 memhog 进程将被添加到 cgrouplimitmem
并限制在内存子系统中。- 任何用户运行的 cpuhog 进程将被添加到 cgroup
limitcpu
并限制在 cpu 子系统中。
我们需要启动 cgred
服务以使 cgrules 配置更改生效,使用以下命令执行此操作:
sudo service cgred start
我们还需要确保启用 cgred
服务以在系统启动时启动,以便我们的规则在重新启动后仍然存在:
sudo chkconfig cgred on
注意: 对于支持 sysconfig 的服务,您可以在 /etc/sysconfig/servicename
中添加变量 CGROUP_DAEMON="subsystem:control_group"
而不是编辑 cgrules.conf
文件。 例如,对于像 httpd 这样的服务,您可以将 CGROUP_DAEMON="blkio:/limitio"
添加到文件 /etc/sysconfig/httpd.conf
以将 httpd 进程添加到 limitio
cgroup。
第 4 步 — 测试
在这一步中,我们将根据我们在 cgrules.conf
中添加的规则验证是否正确执行了 2MiB/s 的磁盘读取吞吐量限制。 为此,我们将安装并运行 hdparm
工具。 hdparm
工具可以设置和查看硬盘的硬件参数,测量读写速度等。 让我们使用以下命令安装 hdparm:
sudo yum install hdparm
现在,让我们运行一个命令来测量硬盘 /dev/vda 的读取速度:
sudo hdparm --direct -t /dev/vda
您应该看到以下输出:
/dev/vda: Timing O_DIRECT disk reads: 6 MB in 3.00 seconds = 2.00 MB/sec
输出显示磁盘读取吞吐量为 2MB/s。 如果同时停止 cgconfig
和 cgred
服务并再次运行上面的 hdparm
命令,您可以看到未实施 cgroup 规则时的原始/默认读取速度。
结论
本教程仅介绍了您可以使用 cgroup 进行的一些基本操作。 还可以创建子 cgroup,计算和报告 cgroup 消耗的资源量,使用 freezer 子系统挂起一组进程等等。
查看以下资源以获取更多详细信息: