前回の最後で
毎年,
今回は4.
nsdelegate オプション
第38回でcgroup v2のマウント方法を紹介しました。第38回で使用していた4.
その後,nsdelegate
というマウントオプションがひとつだけ追加されました。現時点でもcgroup v2のマウントで指定できるオプションは,nsdelegate
のみです。
このオプションは,
このオプションは,
それでは,
cgroup間のプロセスの移動
cgroup名前空間は第34回で説明したとおり,
詳しくは第34回を参照していただくとして,
次の例は4./test01
"にいるはずのプロセスから所属しているcgroupを確認すると,/
)
$ sudo mkdir /sys/fs/cgroup/test01 (test01 cgroupを作成) $ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs (カレントシェルをtest01に登録) 27668 $ sudo unshare --cgroup /bin/bash (cgroup名前空間を作成) # echo $$ (自身のPIDを確認) 27700 # cat /proc/self/cgroup (自分が所属するcgroupを確認) 0::/
念のため,/test01
"にいることが確認できます。
$ sudo cat /proc/27700/cgroup 0::/test01
nsdelegateオプションを指定しない場合
上記の例はnsdelegate
を指定せずにcgroup v2をマウントしていますので,
# mkdir /sys/fs/cgroup/test02 (root直下にtest02を作成) # echo $$ > /sys/fs/cgroup/test02/cgroup.procs (カレントシェルをtest02に移動) # cat /proc/self/cgroup (現在のcgroupを確認) 0::/../test02
元々,/test01
"にいたプロセスを,/test02
に移動させました。すると,/../
"に所属していると表示されました。rootの親cgroupの配下の"test02" cgroupに所属しているということで,
名前空間を作るという操作は,
早速試してみましょう。
nsdelegateオプションを指定した場合
すでにcgroup v2をマウントしている場合,nsdelegate
オプションを指定してマウントできます。そして,
$ sudo mount -t cgroup2 -o remount,nsdelegate /sys/fs/cgroup/ (nsdelegateオプションを指定して再マウント) $ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs 27668 $ sudo unshare --cgroup /bin/bash (cgroup名前空間を作成) # cat /proc/self/cgroup (自分が所属するcgroupを確認) 0::/
ここまでは先のnsdelegateを指定していないときの例と同じです。それではカレントシェルのPIDを"test02"に移動させてみましょう。
# echo $$ > /sys/fs/cgroup/test02/cgroup.procs bash: echo: write error: No such file or directory # ls /sys/fs/cgroup/test02/cgroup.procs /sys/fs/cgroup/test02/cgroup.procs
上のように"No such file or directory"とエラーになりました。しかし"test02" cgroupは存在しています。
つまり"/test01
"をrootとしてcgroup名前空間が作られているので,
ちなみに,
cgroupの権限委譲
連載の第40回で説明したとおり,
- cgroup
(ディレクトリ) への書き込み権限 - cgroup内の
cgroup.
ファイルへの書き込み権限procs
そして,
この権限委譲を行うには,nsdelegate
オプションが導入されてからは,nsdelegate
オプション付きでcgroup v2をマウントするという方法が採れるようになりました。
nsdelegateオプションを指定しない場合
まずはnsdelegate
を指定しない方法を改めて紹介します。ここではあえて対象となるcgroupで,
準備として,io
,pids
,memory
コントローラが使えるように設定します。
$ sudo mount -t cgroup2 cgroup2 /sys/fs/cgroup/ (マウント) $ echo "+io +pids +memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgroupでio, pids, memoryコントローラが使えるように設定) +io +pids +memory $ cat /sys/fs/cgroup/cgroup.subtree_control io memory pids (設定された)
このあたりの操作は第38回で紹介したとおりです。
ここで"test01" cgroupを作成します。そして一般ユーザである"gihyo"ユーザに対して,
$ sudo mkdir /sys/fs/cgroup/test01 (cgroup作成) $ sudo chown gihyo /sys/fs/cgroup/test01 (ディレクトリ所有権をgihyoに) $ sudo chown gihyo /sys/fs/cgroup/test01/* (ディレクトリ内のファイル所有権をgihyoに)
通常はディレクトリとcgroup.
ファイルにのみアクセス権を与えることが一般的です。ここでは,nsdelegate
オプションを指定した場合との比較のためにあえてこのようにしています。
カレントシェルのPIDを"test01" cgroupに登録します。
$ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs
(カレントシェルをtest01に登録)
4352
ここでユーザ名前空間とともにcgroup名前空間を作成します。現在のユーザである"gihyo"ユーザをユーザ名前空間内の"root"ユーザにマッピングするために--map-root-user
オプションを指定しています。
$ unshare --user --cgroup --map-root-user /bin/bash (cgroup名前空間を作成しbashを実行) # cat /proc/self/cgroup (cgroup名前空間内でrootにいることを確認) 0::/
ここではpids.
に制限を設定することにして,pids.
ファイルに制限値を設定してみます。
# ls -l /sys/fs/cgroup/test01/pids.max (pids.maxファイルに書き込み権があることを確認) -rw-r--r-- 1 root nogroup 0 11月 30日 19:51 /sys/fs/cgroup/test01/pids.max # echo 50 > /sys/fs/cgroup/test01/pids.max (制限値の書き込み) # cat /sys/fs/cgroup/test01/pids.max 50 (書き込めたことを確認)
無事にファイルに制限値を書き込めたことが確認できました。アクセス権から考えて予想できる動きではないかと思います。
nsdelegateオプションを指定した場合
それではnsdelegate
オプションを指定してcgroup v2をマウントして試してみましょう。
マウント後,io
,pids
,memory
コントローラが使えるようにします。
$ sudo mount -t cgroup2 -o nsdelegate cgroup2 /sys/fs/cgroup/ (マウント) $ echo "+io +pids +memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgroupでio, pids, memoryコントローラが使えるように設定) +io +pids +memory $ cat /sys/fs/cgroup/cgroup.subtree_control io memory pids (設定された)
そして,
$ sudo mkdir /sys/fs/cgroup/test01 (cgroup作成) $ sudo chown gihyo /sys/fs/cgroup/test01 (ディレクトリ所有権をgihyoに) $ sudo chown gihyo /sys/fs/cgroup/test01/* (ディレクトリ内のファイル所有権をgihyoに)
ここでも,nsdelegate
オプションを指定しないときの例と同様に,
$ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs
(カレントシェルをtest01に登録)
4399
次に,
$ unshare --user --cgroup --map-root-user /bin/bash (cgroup名前空間を作成しbashを実行) # cat /proc/self/cgroup 0::/ (cgroup名前空間内でrootにいることを確認)
所有権を設定していますので"test01"直下に存在するpid.
ファイルには書き込み権があります。
# ls -l /sys/fs/cgroup/test01/pids.max (pids.maxファイルに書き込み権があることを確認) -rw-r--r-- 1 root nogroup 0 11月 30日 20:02 /sys/fs/cgroup/test01/pids.max # echo 50 > /sys/fs/cgroup/test01/pids.max -bash: echo: write error: Operation not permitted (書き込めない)
上の例のように,EPERM
が返ります)。