我在 Ubuntu 20.04 LTS 服务器中有 3 个组,分别是 group1、group2、group3。我想限制每个组的 CPU 和内存。
- Group1 仅允许使用 20% CPU 和 10GB RAM
- Group2 仅允许使用 30% 的 CPU 和 15GB RAM
- Group3 仅允许使用 50% CPU 和 20GB RAM
在 20.04 LTS 服务器版本中使用 systemd 和 cgroup 可以实现吗?或者还有其他方法吗?
答案1
我知道这可能有点晚了,但以下是对我有用的方法。这些步骤是在 Pop! OS 20.04(Ubuntu 20.04 的下游版本)上运行的,但我认为它们也可以在 Ubuntu 服务器上运行。您可能希望在超级用户(提升)终端中运行所有这些命令。只需使用 即可输入sudo su
。
接下来,我将设置 cgroup 限制,以便属于该组的用户cglims
只能使用 95% 的 CPU 和 28 GB 的 RAM。您可以相应地进行更改(添加多个组、更改目标名称、限制等)。我使用 vim ( vi
),您可以使用任何编辑器。
安装
cgroup-tools
包apt install cgroup-tools -y
从文档复制默认配置
cp /usr/share/doc/cgroup-tools/examples/cgred.conf /etc/ # Verify file view /etc/cgred.conf
创建 cgroup 约束(配置)文件
vi /etc/cgconfig.conf
在文件中输入以下内容
group ucglims { cpu { cpu.cfs_quota_us=95000; } memory { memory.limit_in_bytes = 28g; } }
名称
ucglims
是目的地(用于提及约束)。它不是组名。创建将用户、组映射到资源和目的地的规则。
vi /etc/cgrules.conf
在文件中输入以下内容
#<user> #<controllers> #<destination> @cglims cpu,memory ucglims
这意味着组中的用户
cglims
将被限制在目的地的cpu
和memory
(RAM)限制内ucglims
(前面已描述)。解析并应用配置
# Parse /usr/sbin/cgconfigparser -l /etc/cgconfig.conf # Apply /usr/sbin/cgrulesengd -vvv
上述命令激活了 cgroup 限制。你可以测试一下。假设你
test123
在组中有一个用户cglims
。以该用户身份登录并运行# Login as test123 (shouldn't be elevated; open separate terminal) su test123 # See if this is getting populated cat /sys/fs/cgroup/memory/ucglims/tasks cat /sys/fs/cgroup/cpu/ucglims/tasks # Run the following for 'test123' user. It should fail # WARN: This tries getting 40 GB RAM stress -m 4 --vm-bytes 10G --vm-keep -t 10
上面的最后一个命令应该会失败(来自
test123
)。至少,您会看到在 RAM 达到 28GB 限制后,它将开始使用交换(而不是 RAM)。如果交换空间不足,进程将被终止(但留下 28GB,其余 RAM 仍可用)。您可以使用压力也适用于其他类型的极限测试。
我们必须使其持久化(这样重启后就不会丢失)。我们将创建
systemd
服务来实现这一点。创建解析服务
vi /etc/systemd/system/cgconfigparser.service
输入以下内容
[Unit] Description=cgroup config parser After=network.target [Service] User=root Group=root ExecStart=/usr/sbin/cgconfigparser -l /etc/cgconfig.conf Type=oneshot [Install] WantedBy=multi-user.target
创建应用规则的服务
vi /etc/systemd/system/cgrulesgend.service
输入以下内容
[Unit] Description=cgroup rules generator After=network.target cgconfigparser.service [Service] User=root Group=root Type=forking EnvironmentFile=-/etc/cgred.conf ExecStart=/usr/sbin/cgrulesengd Restart=on-failure [Install] WantedBy=multi-user.target
现在重新加载 systemd 守护程序,启用服务并启动它们
# Reload context daemon to 'discover' everything sudo systemctl daemon-reload # Enable services to run on boot sudo systemctl enable cgconfigparser sudo systemctl enable cgrulesgend # Start them sudo systemctl start cgconfigparser sudo systemctl start cgrulesgend
完毕!
您可以在步骤 3 和步骤 4 中添加更多条目以满足您的需要,但我认为上述方法应该可行。
我从以下来源获取了此解决方案
- 关于cgroup及概述:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/ch01
- 有关 cgroup 的更多信息:https://docs.oracle.com/en/operating-systems/oracle-linux/6/admin/ol_cgconfig_cgroups.html
- 再多一点:https://docs.oracle.com/en/operating-systems/oracle-linux/6/admin/ol_cgrules_cgroups.html
- 系统服务:https://www.shubhamdipt.com/blog/how-to-create-a-systemd-service-in-linux/