前回までに引き続き、
Linuxでは、
非特権ユーザに対する権限委譲

デフォルトではcgroupを操作する権限は特権ユーザにしかありません。一般ユーザ権限で起動する非特権コンテナを起動する場合などでは、
たとえば、
- cgroup B以下にcgroupを作れる権限
- cgroup B以下でプロセスを自由に登録できる権限
を与えれば良いでしょう

cgroup B上のコントローラを制御するファイルについては、
もちろん、
cgroup v1の場合
cgroup v1の場合、
権限 | 実際の書き込み権 | |
---|---|---|
1 | cgroup B以下にcgroupを作れる権限 | ディレクトリBへの書き込み権 |
2 | cgroup B以下でプロセスを自由に登録できる権限 | 登録先cgroup内のcgroup. , tasks ファイルへの書き込み権 |
実際に試してみましょう。図1に対応させるためにcgroup_
というcgroupを作成し、ubuntu
ユーザにします。
$ whoami ubuntu $ sudo mkdir /sys/fs/cgroup/cpu/cgroup_B (cgroup_B を作成) $ sudo chown ubuntu /sys/fs/cgroup/cpu/cgroup_B/ (cgroup_Bの所有権をubuntuに) $ ls -ld /sys/fs/cgroup/cpu/cgroup_B/ (ubuntuユーザ所有になっている) drwxr-xr-x 2 ubuntu root 0 Feb 27 20:04 /sys/fs/cgroup/cpu/cgroup_B/
これで子cgroupを作る準備はできましたので、cgroup_
とcgroup_
を作ってみましょう。
$ mkdir /sys/fs/cgroup/cpu/cgroup_B/cgroup_C $ mkdir /sys/fs/cgroup/cpu/cgroup_B/cgroup_D $ $ ls -ld /sys/fs/cgroup/cpu/cgroup_B/cgroup_* drwxrwxr-x 2 ubuntu ubuntu 0 Feb 27 20:07 /sys/fs/cgroup/cpu/cgroup_B/cgroup_C drwxrwxr-x 2 ubuntu ubuntu 0 Feb 27 20:07 /sys/fs/cgroup/cpu/cgroup_B/cgroup_D
通常のディレクトリを作成する際と同じで、cgroup_
ディレクトリはubuntu
ユーザ所有ですので、
$ ls -l /sys/fs/cgroup/cpu/cgroup_B/cgroup_C total 0 -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cgroup.clone_children -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cgroup.procs -r--r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpuacct.stat -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpuacct.usage -r--r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpuacct.usage_percpu -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpu.cfs_period_us -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpu.cfs_quota_us -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpu.shares -r--r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 cpu.stat -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 notify_on_release -rw-r--r-- 1 ubuntu ubuntu 0 Feb 27 20:07 tasks
上の実行例のようにcgroup_
、cgroup_
以下にファイルは、ubuntu
ユーザ所有ですので自由にcgroup操作ができます。
次にプロセスの登録について見てみましょう。cgroup_
のtasks
、cgroup.
ファイルの所有権をubuntu
に変更し、
$ sudo chown ubuntu /sys/fs/cgroup/cpu/cgroup_B/tasks (cgroup_Bのtasksファイルの所有権をubuntuに) $ sudo chown ubuntu /sys/fs/cgroup/cpu/cgroup_B/cgroup.procs (cgroup_Bのcgroup.procsファイルの所有権をubuntuに) $ echo $$ 1690 $ echo $$ > /sys/fs/cgroup/cpu/cgroup_B/tasks (プロセスをcgroup_Bに登録) $ cat /sys/fs/cgroup/cpu/cgroup_B/tasks (登録できている) 1690 2285
cgroup_
にプロセスが登録できました。cgroup_
やcgroup_
以下のファイルの所有者はubuntu
ですから、
$ echo $$ > /sys/fs/cgroup/cpu/cgroup_B/cgroup_C/tasks (上でcgroup_Bに登録したプロセスをcgroup_Cに移動) $ cat /sys/fs/cgroup/cpu/cgroup_B/tasks (cgroup_Bにはプロセスはない) $ cat /sys/fs/cgroup/cpu/cgroup_B/cgroup_C/tasks (cgroup_Cに移動した) 1690 2316 $ echo $$ > /sys/fs/cgroup/cpu/cgroup_B/cgroup_D/tasks $ cat /sys/fs/cgroup/cpu/cgroup_B/cgroup_D/tasks (cgroup_Dに移動した) 1690 2328 $ cat /sys/fs/cgroup/cpu/cgroup_B/tasks (再度cgroup_Bに移動した) 1690 2343
cgroup v1でプロセスをcgroup間で移動させる場合は、
- 移動先の
tasks
、cgroup.
ファイルへの書き込み権があるproc - 移動
(書き込み) しようとするプロセスの実効UIDが、 ターゲットとなるプロセスの実UIDもしくは保存set-user-idと一致する
上のような条件ですので、

試してみましょう。
$ sudo mkdir /sys/fs/cgroup/cpu/cgroup_{A,B} (cgroup_A, B作成) $ sudo chown ubuntu /sys/fs/cgroup/cpu/cgroup_{A,B} (A, Bの所有権の変更) $ mkdir /sys/fs/cgroup/cpu/cgroup_A/cgroup_C (cgroup_C作成) $ mkdir /sys/fs/cgroup/cpu/cgroup_B/cgroup_D (cgroup_D作成) $ echo $$ > /sys/fs/cgroup/cpu/cgroup_A/cgroup_C/tasks (Cにプロセスを登録) $ cat /sys/fs/cgroup/cpu/cgroup_A/cgroup_C/tasks | grep $$ 1622 (登録されている) $ echo $$ > /sys/fs/cgroup/cpu/cgroup_B/cgroup_D/tasks (Dにプロセスを移動) $ cat /sys/fs/cgroup/cpu/cgroup_B/cgroup_D/tasks | grep $$ 1622 (移動している)
図3の通りのcgroupを作成して、cgroup_
に登録したプロセスをcgroup_
に移動できました。
cgroup v2の場合
cgroup v2の場合、
権限 | 実際の書き込み権 | |
---|---|---|
1 | cgroup B以下にcgroupを作れる権限 | ディレクトリBへの書き込み権 |
2 | cgroup B以下でプロセスを自由に登録できる権限 | 登録先cgroup内のcgroup. ファイルへの書き込み権 |
プロセスがもともと所属しているcgroupと登録先cgroupの共通の祖先となるcgroup内のcgroup. ファイルへの書き込み権 |
実効UIDの制限がなくなった理由は、
文字で書くと条件が少しわかりづらいですね。実際に、

図4のような構成のツリーがあるとします。まずはcgroup_
を作成し、cgroup.
ファイルの所有権を変更します。
$ sudo chown ubuntu /sys/fs/cgroup/cgroup_B (cgroup Bをubuntuユーザ所有に) $ sudo chown ubuntu /sys/fs/cgroup/cgroup_B/cgroup.procs (cgroup Bのcgroup.procsファイルをubuntuユーザ権限に) $ ls -al /sys/fs/cgroup/cgroup_B total 0 drwxr-xr-x 4 ubuntu root 0 Mar 7 20:27 ./ dr-xr-xr-x 4 root root 0 Mar 7 20:14 ../ -r--r--r-- 1 root root 0 Mar 7 20:38 cgroup.controllers -r--r--r-- 1 root root 0 Mar 7 20:38 cgroup.events -rw-r--r-- 1 ubuntu root 0 Mar 7 20:25 cgroup.procs -rw-r--r-- 1 root root 0 Mar 7 20:38 cgroup.subtree_control (cgroup Bディレクトリとcgroup.procsファイルのみubuntuの所有となっている)
root cgroupからcgroup Bへのプロセスの移動
図4のubuntu
ユーザでcgroup_
のcgroup.
に登録を試みます。cgroup v1の場合はcgroup B内のcgroup.
に書き込み権があれば、
$ whoami
ubuntu
$ echo $$ > /sys/fs/cgroup/cgroup_B/cgroup.procs
-bash: echo: write error: Permission denied
(ユーザ自身の権限で実行されているプロセスを登録しようとしたが失敗した)
しかしcgroup v2では、cgroup.
ファイルはubuntu
ユーザの所有であり、
これは表2で示した条件の2番目に引っかかったためです。この場合、ubuntu
ユーザはroot cgroupのcgroup.
ファイルに対する権限を持っていませんので、
これは、
この考え方に従い、cgroup_
に登録しましょう。
$ echo $$ | sudo tee /sys/fs/cgroup/cgroup_B/cgroup.procs 3126 (root権限でubuntuユーザ権限で動いているプロセスをcgroup_Bに登録) $ grep $$ /sys/fs/cgroup/cgroup_B/cgroup.procs 3126 (登録できた)
この操作はroot権限で行っていますので登録できます。
権限があるcgroup間でのプロセスの移動(共通のcgroup配下のcgroup間)
それではcgroup_
配下にcgroup_
とcgroup_
を作成し、
$ whoami ubuntu $ mkdir /sys/fs/cgroup/cgroup_B/cgroup_{D,E} (ubuntuユーザ権限でcgroup D,Eを作成) $ ls -d /sys/fs/cgroup/cgroup_B/cgroup_* /sys/fs/cgroup/cgroup_B/cgroup_D/ /sys/fs/cgroup/cgroup_B/cgroup_E/ (問題なく作成できた)
cgroup_
はubuntu
ユーザ所有ですので、cgroup_
とcgroup_
は問題なく作成できました。
それでは、cgroup_
へ移動させたプロセスをcgroup_
に移動させましょう。図4の
$ whoami
ubuntu
$ echo $$ > /sys/fs/cgroup/cgroup_B/cgroup_D/cgroup.procs
(自身の所有であるcgroup_Bのcgroup.procsに登録されたプロセスを自身の所有であるcgroup Dに移動)
$ grep $$ /sys/fs/cgroup/cgroup_B/cgroup_D/cgroup.procs
3126
今度はエラーなく作成できました。これはcgroup_
がcgroup_
とcgroup_
の共通の祖先」
cgroup_
のD cgroup.
はprocs ubuntu
ユーザが所有cgroup_
とD cgroup_
の共通の祖先であるB cgroup_
のB cgroup.
ファイルはprocs ubuntu
ユーザが所有
となり、
次に、cgroup_
からcgroup_
へのプロセスの移動を見てみましょう。図4の
cgroup_
のE cgroup.
はprocs ubuntu
ユーザが所有cgroup_
とD cgroup_
の共通の祖先であるE cgroup_
のB cgroup.
ファイルはprocs ubuntu
ユーザが所有
ですので、
$ whoami ubuntu $ ls -l /sys/fs/cgroup/cgroup_B/cgroup.procs -rw-r--r-- 1 ubuntu root 0 Mar 7 20:25 /sys/fs/cgroup/cgroup_B/cgroup.procs $ ls -l /sys/fs/cgroup/cgroup_B/cgroup_E/cgroup.procs -rw-r--r-- 1 ubuntu ubuntu 0 Mar 7 20:57 /sys/fs/cgroup/cgroup_B/cgroup_E/cgroup.procs (共通の祖先と移動先のcgroup.procsファイルに権限があることの確認) $ grep $$ /sys/fs/cgroup/cgroup_B/cgroup_D/cgroup.procs 3126 (cgroup Dにプロセスが登録されていることの確認) $ echo $$ > /sys/fs/cgroup/cgroup_B/cgroup_E/cgroup.procs (プロセスをcgroup Eに移動) $ grep $$ /sys/fs/cgroup/cgroup_B/cgroup_E/cgroup.procs 3126 (移動できた)
移動できました。
権限があるcgroup間でのプロセスの移動(共通のcgroup配下でないcgroup間)
別の例を紹介しましょう。

図5のようにroot cgroup直下にcgroup_
とcgroup_
を作成し、cgroup_
、cgroup_
を作成します。
$ ls -ld /sys/fs/cgroup/cgroup_? (cgroup_A,Bはubuntuユーザ所有) drwxr-xr-x 3 ubuntu root 0 3月 14日 19:38 /sys/fs/cgroup/cgroup_A/ drwxr-xr-x 3 ubuntu root 0 3月 14日 19:38 /sys/fs/cgroup/cgroup_B/ $ ls -l /sys/fs/cgroup/cgroup_?/cgroup.procs (ubuntuユーザはcgroup_A,Bのcgroup.procsに書き込み権あり) -rw-r--r-- 1 ubuntu root 0 3月 14日 19:33 /sys/fs/cgroup/cgroup_A/cgroup.procs -rw-r--r-- 1 ubuntu root 0 3月 14日 19:33 /sys/fs/cgroup/cgroup_B/cgroup.procs $ ls -ld /sys/fs/cgroup/cgroup_?/cgroup_? (cgroup_C,Dはubuntuユーザ所有) drwxr-xr-x 2 ubuntu users 0 3月 14日 19:38 /sys/fs/cgroup/cgroup_A/cgroup_C/ drwxr-xr-x 2 ubuntu users 0 3月 14日 19:38 /sys/fs/cgroup/cgroup_B/cgroup_D/ $ ls -l /sys/fs/cgroup/cgroup_?/cgroup_?/cgroup.procs (ubuntuユーザはcgroup_C,Dのcgroup.procsに書き込み権あり) -rw-r--r-- 1 ubuntu users 0 3月 14日 19:38 /sys/fs/cgroup/cgroup_A/cgroup_C/cgroup.procs -rw-r--r-- 1 ubuntu users 0 3月 14日 19:38 /sys/fs/cgroup/cgroup_B/cgroup_D/cgroup.procs
以上のようにcgroup_ubuntu
ユーザ所有のグループで、cgroup.
ファイルの所有権もubuntu
ユーザになっており、
ここでcgroup_
からcgroup_
へプロセスが移動できるでしょうか? 試してみましょう。
まずはcgroup_
にプロセスを登録します。root cgroupからの移動になりますのでroot権限で移動させます。
$ echo $$ | sudo tee /sys/fs/cgroup/cgroup_A/cgroup_C/cgroup.procs 3058 (root権限でcgroup_Cにプロセスを登録) $ grep $$ /sys/fs/cgroup/cgroup_A/cgroup_C/cgroup.procs 3058 (登録されている)
これでcgroup_
にプロセスが登録された状態になりました。つぎに、cgroup_
からcgroup_
に移動させてみましょう。
$ echo $$ > /sys/fs/cgroup/cgroup_B/cgroup_D/cgroup.procs -bash: echo: write error: Permission denied
cgroup_
のcgroup.
はubuntu
ユーザ所有であり、cgroup_
とcgroup_
の共通の祖先をたどるとroot cgroupになります。root cgroupのcgroup.
ファイルに対してubuntu
ユーザは書き込み権限を持っていませんので、
このような移動ができない理由を考えてみましょう。
図5の構造を見ると、cgroup_
以下とcgroup_
以下はそれぞれ独立したコンテナとみなせます。いくら同じユーザ権限で動いているコンテナとはいえ、
このようにcgroup v2では、
まとめ
今回を含めて4回でcgroup v2コアの機能を紹介してきました。
今回は特権を持たないユーザに対して、
cgroup v2には、
次回以降はしばらく私ではなく、
udzura さんは、
お楽しみに。