如何使用 systemd 創建使用者 cgroup
我
lxc
在Arch 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中啟動我的非特權容器,但不能在其他任何地方啟動。
- 有人可以解釋這種行為嗎?
- 有人找到了一種更好的方法來
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
(通過. script
The.
對這個工作很重要!)是我不只是打開一個新會話user
但是將目前 shell 添加為在這個新 cgroup 中執行的程序。我可以通過在子shell中執行腳本然後下降到cgroup
層次結構中來達到相同的效果chb
subcgroup
並用於echo $$ > tasks
將目前 shell 添加到chb cgroup hierarchy
.因此,當我
lxc
在目前 shell 中執行時,我的容器也將成為目前所屬的所有chb
subcgroup
sshell
的成員。也就是說 mycontainer
繼承了my 的cgroup
狀態shell
。這也解釋了為什麼它在不屬於目前chb
subcgroup
s 的任何其他 shell 中不起作用。我仍然通過
2.
。我們可能需要等待systemd
更新或進一步的Kernel
開發才能systemd
採用一致的行為,但無論如何我更喜歡手動設置,因為它會迫使您了解自己在做什麼。