前回までに引き続き,
Linuxでは,
非特権ユーザに対する権限委譲
デフォルトではcgroupを操作する権限は特権ユーザにしかありません。一般ユーザ権限で起動する非特権コンテナを起動する場合などでは,
たとえば,
- cgroup B以下にcgroupを作れる権限
- cgroup B以下でプロセスを自由に登録できる権限
を与えれば良いでしょう
cgroup B上のコントローラを制御するファイルについては,
もちろん,
cgroup v1の場合
cgroup v1の場合,
表1 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に変更し,
- ※1)
- 実際は`tasks`か`cgroup.
procs`のどちらかに権限を与え, 与えたファイルに書き込めば, 他方の所有権が`root`のままでもプロセスは登録できるようです。
$ 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_に移動できました。