Systemd

如何使用 systemd 創建使用者 cgroup

  • August 7, 2020

lxcArch Linux. 以下是基本系統資訊:

[chb@conventiont ~]$ uname -a
Linux conventiont 3.17.4-Chb #1 SMP PREEMPT Fri Nov 28 12:39:54 UTC 2014 x86_64 GNU/Linux

這是一個自定義/編譯核心,具有user namespace enabled

[chb@conventiont ~]$ lxc-checkconfig 
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

[chb@conventiont ~]$ systemctl --version
systemd 217
+PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD +IDN 

不幸的是,systemd目前不能很好地發揮作用lxc。特別cgroups是為非 root 使用者設置似乎效果不佳,或者我太不熟悉如何做到這一點。lxc只有當容器可以在/sys/fs/cgroup/XXX/*. 然而,這是不可能的,lxc因為將cgroup 層次結構systemd安裝在. 一種解決方法似乎是執行以下操作:root``/sys/fs/cgroup/*

for d in /sys/fs/cgroup/*; do
       f=$(basename $d)
       echo "looking at $f"
       if [ "$f" = "cpuset" ]; then
               echo 1 | sudo tee -a $d/cgroup.clone_children;
       elif [ "$f" = "memory" ]; then
               echo 1 | sudo tee -a $d/memory.use_hierarchy;
       fi
       sudo mkdir -p $d/$USER
       sudo chown -R $USER $d/$USER
       echo $$ > $d/$USER/tasks
done

此程式碼在層次結構中為非特權使用者創建相應的cgroup目錄。cgroup但是,發生了一些我不明白的事情。在執行上述操作之前,我會看到:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/
7:net_cls:/
6:freezer:/
5:devices:/
4:memory:/
3:cpu,cpuacct:/
2:cpuset:/
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope

執行上述程式碼後,我在 shell 中看到我執行它:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/chb
7:net_cls:/chb
6:freezer:/chb
5:devices:/chb
4:memory:/chb
3:cpu,cpuacct:/chb
2:cpuset:/chb
1:name=systemd:/chb

但在任何其他外殼中,我仍然看到:

[chb@conventiont ~]$ cat /proc/self/cgroup 
8:blkio:/
7:net_cls:/
6:freezer:/
5:devices:/
4:memory:/
3:cpu,cpuacct:/
2:cpuset:/
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope

lxc因此,我可以在執行上述程式碼的 shell中啟動我的非特權容器,但不能在其他任何地方啟動。

  1. 有人可以解釋這種行為嗎?
  2. 有人找到了一種更好的方法來cgroups使用目前版本的systemd( >= 217) 設置所需的內容嗎?

更好和更安全的解決方案是安裝cgmanager和執行它systemctl start cgmanager(在systemd基於 - 的發行版上)。您可以讓您的root使用者,或者如果您sudo在主機上擁有權限,則cgroups可以在所有控制器中為您的非特權使用者創建:

sudo cgm create all $USER
sudo cgm chown all $USER $(id -u $USER) $(id -g $USER)

一旦為您的非特權使用者創建了它們,她/他可以使用以下方法將他有權訪問的程序移動到cgroup每個控制器中:

cgm movepid all $USER $PPID

比我發布的 shell 腳本更安全、更快、更可靠。

手動解決方案:

回答 1。

for d in /sys/fs/cgroup/*; do
       f=$(basename $d)
       echo "looking at $f"
       if [ "$f" = "cpuset" ]; then
               echo 1 | sudo tee -a $d/cgroup.clone_children;
       elif [ "$f" = "memory" ]; then
               echo 1 | sudo tee -a $d/memory.use_hierarchy;
       fi
       sudo mkdir -p $d/$USER
       sudo chown -R $USER $d/$USER
       echo $$ > $d/$USER/tasks
done

當我編寫該腳本時,我並不知道到底發生了什麼,但是閱讀cgroups 文件並進行一些實驗有助於我理解發生了什麼。我在這個腳本中所做的基本上是cgroup為目前會話創建一個新會話,user這就是我上面已經說過的。當我在目前執行這些命令shell或在腳本中執行它們並使其在目前shell而不是在 a中進行評估時subshell(通過. scriptThe.對這個工作很重要!)是我不只是打開一個新會話user但是將目前 shell 添加為在這個新 cgroup 中執行的程序。我可以通過在子shell中執行腳本然後下降到cgroup層次結構中來達到相同的效果chb subcgroup並用於echo $$ > tasks將目前 shell 添加到chb cgroup hierarchy.

因此,當我lxc在目前 shell 中執行時,我的容器也將成為目前所屬的所有chb subcgroupsshell的成員。也就是說 mycontainer繼承了my 的cgroup狀態shell。這也解釋了為什麼它在不屬於目前chb subcgroups 的任何其他 shell 中不起作用。

我仍然通過2.。我們可能需要等待systemd更新或進一步的Kernel開發才能systemd採用一致的行為,但無論如何我更喜歡手動設置,因為它會迫使您了解自己在做什麼。

引用自:https://unix.stackexchange.com/questions/170998