cgroup v2 の nsdelegate
オプション第 2 弾です。
前回紹介したのは、cgroup namespace を作ると cgroup root を超えたプロセスの移動が禁止されるという機能でした。
これはユーザに関わらず関係するお話でしたが、今回は一般ユーザで namespace(つまりコンテナ)を作ったときのお話です。
私の連載の第 40 回 で紹介したとおり、cgroup v1 に比べて cgroup v2 は一般ユーザでプロセスを移動できる条件が厳しくなりました。ただ、これは実際のユースケースに合っている、というのは連載で書いたとおりです。
一般ユーザに cgroup ツリーを権限委譲する際には、権限委譲する root cgroup に当たる cgroup には、
という権限を与えました。
cgroup 内でコントローラを使えるようにしていても、権限委譲の root cgroup 内のコントローラ関連のファイルには権限は与えません。コンテナに与えるリソースを定義するのはあくまでホストの管理者であって、コンテナの管理者が自身に与えられたリソースを変更できるとマズいから、というのは納得の行くところだと思います。
これを実現するために、前述のようにホスト側の管理者がパーミッションの調整を行っていたわけですが、nsdelegate
オプションをつけると、これが自動的に行われます。
nsdelegate
の有無で処理がどう変わるか見てみましょう。処理は
- cgroup v2 をマウントする(オプション有無)
cgroup.subtree_control
にコントローラを登録- cgroup 作成
- cgroup ディレクトリとそれ以下のファイルに所有権を与える
- cgroup にシェルの PID 登録
- cgroup namespace 作成
- 作成した cgroup のコントローラを制御するファイル(ここでは
pids.max
)に制限値を書き込む
という処理をやってみました。
nsdelegate
を付けない場合
では、まず普通に cgroup v2 をマウントして処理をすすめましょう。
# mount -t cgroup2 cgroup2 /sys/fs/cgroup/ (1) # echo "+io +pids +memory" > /sys/fs/cgroup/cgroup.subtree_control (2) # mkdir /sys/fs/cgroup/test01 (3) # chown karma /sys/fs/cgroup/test01 (4) # chown karma /sys/fs/cgroup/test01/* (4) $ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs (5) 4013 $ unshare --user --cgroup --map-root-user (6) root@plamo70b2:~# ls -l /sys/fs/cgroup/test01 (権限を確認) : (snip) -rw-r--r-- 1 root nogroup 0 9月 7日 01:03 pids.max
このように pids.max
には書き込み権がありますね。
一応 cgroup root にいるか確認します。
# cat /proc/$$/cgroup 0::/
ここで pids.max
に制限値として 50
を書き込みます。
# echo 50 > /sys/fs/cgroup/test01/pids.max (7) # cat /sys/fs/cgroup/test01/pids.max 50
登録できました。普通の cgroup v2 のコントローラ操作ですね。
nsdelegate
を付けた場合
nsdelegate
をオプションで与える以外は同じ操作をしてみます。
# mount -t cgroup2 -o nsdelegate cgroup2 /sys/fs/cgroup/ (1) # echo "+io +pids +memory" > /sys/fs/cgroup/cgroup.subtree_control (2) # mkdir /sys/fs/cgroup/test01 (3) # chown karma /sys/fs/cgroup/test01 (4) # chown karma /sys/fs/cgroup/test01/* (4) $ echo $$ | sudo tee /sys/fs/cgroup/test01/cgroup.procs (5) 4013 $ unshare --user --cgroup --map-root-user (6) # ls -l /sys/fs/cgroup/test01/ : (snip) -rw-r--r-- 1 root nogroup 0 9月 7日 01:25 pids.max
先ほどと同様に書き込み権はあります。
cgroup root にいることも確認しておきます。
# cat /proc/$$/cgroup 0::/
先ほどと同様に制限値を書き込みます。
# echo 50 > /sys/fs/cgroup/test01/pids.max (7) -bash: echo: 書き込みエラー: 許可されていない操作です
今回は先ほどと違ってエラーになりました。
このように権限委譲した場合、その root cgroup には限定的な権限のみを与えるのが nsdelegate
のもうひとつの機能です。
つまり cgroup namespace (つまりコンテナ)を権限委譲の境界とし、その root cgroup (コンテナの root cgroup)には限定的な権限を与え、それ以下の cgroup のみ権限委譲対象のユーザ管理とするわけです。