简述cgroups

cgroups是一种linux内核提供的一项功能,能够用于审核,管理,限制进程组。

能够限制诸如cpu、内存、最大进程数等资源占用量之类的……?

这里,则尝试使用systemd对cgroups进行配置。

授权控制

cgroup允许用户将分配给自己的控制组的资源进行重新分配,但是这需要额外的授权(委派)。

按照archwiki相关页面的介绍,以管理员账户执行 systemctl edit user@[用户id].service 1(此处,用户id为1000),以允许用户对控制组进行控制。

然后,在打开的文件中,将Delegate的值改为yes,也就是

1
2
[Service]
Delegate=yes

该Delegate值,也可以用于单独授权某些控制权限,这个值默认是 pids memory ,也就是允许用户可以对自己所能调动的进程数和内存资源进行再分配。也可以加上cpu和io等等,以允许对CPU和磁盘等访问的资源占用进行控制。值填为yes则是允许所有。

不过这边执行上面的命令一直报错就是了……

1
Editing "/etc/systemd/system/[email protected]/override.conf" canceled: temporary file is empty.

所以这边使用 sudo nano /etc/systemd/system/[email protected]/override.conf 2改成手动编辑来加入了。

编辑完成后,就需要重启计算机以加载这一设置

重启完成后,可以使用下述命令来检查这一设置

1
cpuset cpu io memory pids

临时设置限制环境启动程序

如果只是临时想以资源受限环境启动一个程序,可以使用 systemd-run -p 命令来实现这一点。

例如下面:

1
systemd-run --user -p MemoryHigh=0.75G -p MemoryMax=1G -p CPUQuota=70% make

这个命令会启动make命令,并限制内存最大占用软限制为0.75G(如果实在无法避免,可以短暂的越过这一限制,但是进程的运行速度会大打折扣,并且系统会尽快回收超出的内存),并设置内存最大占用硬限制为1G(越过此限制会导致程序被杀死),CPU时间限额为70%(最多只能使用70%的单颗CPU时间)

关于更多可以使用的资源分配属性,可以参考systemd的systemd.resource-control页面3。而关于systemd-run命令的更多介绍,也可以参考官方对该命令编写的文档4

自定义cgroup,创建规则文件

当然,systemd也支持将这些限制指令保存在文件中,以方便在其他地方调用,在systemd中,这类文件叫做slice,控制组单元。这类文件以.slice作为后戳名。

如果用于全系统的话,此类文件一般会保存在 /etc/systemd/system/XXX.slice 中,而用户自定义编辑的slice则可以存放在 ~/.config/systemd/user/ 下。

不过,这篇文章重点在于用户资源的限制,而不关注全系统资源分配,所以此处以非特权模式为例子。

首先在 ~/.config/systemd/user/ 下创建一个新的控制组文件,比如

1
nano ~/.config/systemd/user/browser.slice

然后,在文件中写入[Silce]和想要设置的资源分配规则

1
2
3
[Silce]
MemoryHigh=4G
MemoryMax=4.5G

限制该控制组,内存软限制最大占用2G,硬限制最大占用2.5G,并保存退出。

然后,可以使用 systemd-run --user --slice=browser.slice 调用该控制组,以该控制组启动程序。

1
systend-run --user --slice=browser.silce chromium

结末

这应该是很长时间内的第一次更新吧,大概就是这样子。拖延了很久,总算是,姑且,完成了呢。一篇新的文章。

补充更新,为systemd配置(用户级别的)全局环境变量

虽然说,只是限制程序能够占用的资源的话,上面这些操作已经足够了,但是,这边遇到了一些新的问题。

由于systemd-run启动新的进程时,会在一个清洁的状态下启动服务,也就是不会载入bashrc或者xprofile之类的通常用来设置环境变量的一些配置文件。

这导致了,在使用systemd-run在启动一些具有图形化界面的时候,不会加载输入法相关的环境变量,导致输入法无法在这类进程中正常工作。所以需要为systemd配置环境变量。

systemd默认的用户级手动设置的环境变量设置位置,位于 ~/.config/environment.d/*.conf5,可以在该文件夹下新建一个conf文件以设置环境变量,类似于

  • ~/.config/environment.d/99-fcitx.conf

    1
    2
    3
    
    XMODIFIERS=@im=fcitx
    QT_IM_MODULE=fcitx
    GTK_IM_MODULE=fcitx
    

然后,可以通过重启计算机来载入这类配置。(或者,按文档来看的话,似乎也可以用 /usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator 但是不太确定这边为何无法正常工作……)

总之,重启完成后,大概就可以正常使用输入法了。

脚注


  1. archwiki关于cgroup的介绍:https://wiki.archlinux.org/title/Cgroups ↩︎

  2. systemd可能关于关于这类文件的相关文档:https://www.freedesktop.org/software/systemd/man/[email protected]#,也可以参考金步国先生对该页面的翻译版本http://www.jinbuguo.com/systemd/[email protected] ↩︎

  3. systemd单元的资源限制,官方文档:https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html,也可以参考金步国先生对该页面的翻译版本:http://www.jinbuguo.com/systemd/systemd.resource-control.html ↩︎

  4. systemd-run,官方文档:https://www.freedesktop.org/software/systemd/man/systemd-run.html,也可以参考金步国先生对此的翻译:http://www.jinbuguo.com/systemd/systemd-run.html ↩︎

  5. 关于环境变量配置目录environment.d的官方文档:https://www.freedesktop.org/software/systemd/man/environment.d.html,也可以参考金步国先生对此的翻译:http://www.jinbuguo.com/systemd/environment.d.html ↩︎