前回はcgroup v2で使えるコントローラのうち、
今回はcgroup v2で行われるリソース制御のタイプ、
cgroupとcgroup内ファイルの命名規則
cgroup v1には、
今回の実行例は、
まず、"cgroup."
で始まります。各コントローラ用のインターフェースファイルは"
で始まります。
"
で始まる名前では、.
)"io.
で始まります。
あるcgroupに子cgroupを作成する際には、
このように、
逆にcgroupのインターフェースファイルは、
コントローラ用のインターフェースファイル名で、"
の後のドット.
)
コントローラがリソース分配を行う方法
cgroup v1では、
cgroup v2では、
ウェイト(Weights)
ウェイトは第4回で説明したCPUコントローラの相対配分として紹介した機能で使われているようなリソース配分です。
子cgroupで指定されている数値をすべて足して、
例えば、
ウェイトとして設定できる値は1〜10000の間で、
ウェイトでリソース分配を行う場合の、"
です。このようなファイルの例としてcpu.
があります。
cpu.
を使って、
まず、
$ echo "+cpu" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgroupでCPUコントローラが使えるようにする) +cpu $ cat /sys/fs/cgroup/cgroup.subtree_control (cpuという文字列が書き込まれた) cpu memory pids $ sudo mkdir /sys/fs/cgroup/test (root直下に"test" cgroupを作成) $ cat /sys/fs/cgroup/test/cgroup.controllers cpu memory pids ("test" cgroupでcpuコントローラが使えることを確認)
さて、test
cgroupが作成できましたので、cpu.
ファイルを見てみましょう。
$ ls /sys/fs/cgroup/test/cpu.weight /sys/fs/cgroup/test/cpu.weight (ファイルが存在する) $ cat /sys/fs/cgroup/test/cpu.weight 100 (cgroup作成直後のデフォルト値は"100")
cgroup作成直後で、cpu.
ファイルを確認すると、100
という数値が書かれています。実際に操作をしてみましょう。
$ echo "10000" | sudo tee /sys/fs/cgroup/test/cpu.weight
10000
$ cat /sys/fs/cgroup/test/cpu.weight
10000
$ echo "1" | sudo tee /sys/fs/cgroup/test/cpu.weight
1
$ cat /sys/fs/cgroup/test/cpu.weight
1
$ echo "100000" | sudo tee /sys/fs/cgroup/test/cpu.weight
100000 (上限値以上の数値を書き込むとエラーになる)
tee: /sys/fs/cgroup/test/cpu.weight: Numerical result out of range
範囲内の1
と10000
を書き込むと正常に反映され、100000
を書くとエラーになることが確認できました。
制限(Limits)
制限
この制限は、
制限として、
制限でリソース制限を行う場合の、"
に続けて次のような文字列が付いた名前になります。
- ハードリミットとして絶対的な割り当て制限を行う場合:
max
(例: memory.
)max - ソフトリミットとしてベストエフォートのリソース制限を行う場合:
high
(例: memory.
)high
ここで例としてあげたファイル名はmemory.
とmemory.
で、
cgroupを作成して、memory.
とmemory.
ファイルを見てみましょう。
$ sudo mkdir /sys/fs/cgroup/test2 (cgroupを作成) $ cat /sys/fs/cgroup/test2/memory.max max (デフォルト値はmax) $ cat /sys/fs/cgroup/test2/memory.high max (デフォルト値はmax)
いずれも作成直後のデフォルト値はmax
となっており、
$ echo "128M" | sudo tee /sys/fs/cgroup/test2/memory.max 128M (128MBに制限) $ cat /sys/fs/cgroup/test2/memory.max 134217728 (制限値が書き込まれた) $ echo "max" | sudo tee /sys/fs/cgroup/test2/memory.max max (制限を外すためにmaxという文字列を書き込んだ) $ cat /sys/fs/cgroup/test2/memory.max max (制限値がmaxに書き換わった)
まず"128M"という文字列を書き込み制限値を設定した後に、memory.
ファイルの中身がmax
と書き換わりました。
保護(Protections)
保護
制限と同様に保護もオーバーコミットでき、
また、
保護として、
保護でリソース分配を行う場合の、"
に続けて次のような文字列が付いた名前になります。
- リソースの絶対的な割り当て保証
(保護) を行う場合: min
(例: memory.
)min - リソースのベストエフォートのリソース割り当て保証
(保護) を行う場合: low
(例: memory.
)low
例としてあげたメモリコントローラは、
ここでもmemory.
とmemory.
を使って簡単に動きを見ておきましょう。cgroupを作成し、
$ sudo mkdir /sys/fs/cgroup/test3 (cgroupを作成) $ cat /sys/fs/cgroup/test3/memory.min 0 (デフォルト値は0) $ cat /sys/fs/cgroup/test3/memory.low 0 (デフォルト値は0)
いずれもデフォルト値は0
になっていることが確認できました。数値以外の値として書き込める"max"を書き込み、
$ echo max | sudo tee /sys/fs/cgroup/test3/memory.min (memory.minにmaxという文字列を書き込む) max $ cat /sys/fs/cgroup/test3/memory.min max (maxに書き換わっている) $ echo 128M | sudo tee /sys/fs/cgroup/test3/memory.min 128M (制限値を128MBに設定する) $ cat /sys/fs/cgroup/test3/memory.min 134217728 (制限値が書き込まれた)
このように"max"で最大値が設定できましたし、
割り当て(Allocations)
割り当て
割り当てとして、
現時点ではこのモデルが実装されたコントローラはないようです。
このタイプでの制限では設定値を超えることはできませんので、"
となるようです。
インターフェースファイル内のフォーマット
cgroupを制御するために使われるインターフェースファイルには、
改行で区切られた値
まずは1行に1つ値が書かれたいるタイプのファイルです。
今回、
1つ以上の値が書かれる場合は改行で区切られて1行に1つ値が入ります。例えば、cgroup.
ファイルです。
このタイプのファイルは、
$ cat /sys/fs/cgroup/test3/memory.max max (値が1つだけ書かれたファイル) $ cat /sys/fs/cgroup/user.slice/user-1000.slice/session-1.scope/cgroup.procs (複数の値が1行に1つ書かれたファイル) 740 768 769 1125
スペース区切りの複数の値
1 行に複数の値が書かれる場合があります。例えばcgroup.
やcgroup.
のようなファイルです。
このタイプのファイルは、
$ cat /sys/fs/cgroup/test3/cgroup.controllers memory pids $ cat /sys/fs/cgroup/cgroup.subtree_control memory pids
キーと値
設定項目とそれに対する値を設定するようなケースです。例えば "key_
key_a val_a
のようになります。1 つのファイルに複数、
このタイプは、cpu.
やmemory.
のようなファイルです。
$ sudo mkdir /sys/fs/cgroup/test3 (cgroupの作成) $ echo "+cpu" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgroupでcpuコントローラを使えるようにする) +cpu $ echo $$ | sudo tee /sys/fs/cgroup/test3/cgroup.procs (プロセスを所属させる) 794 $ cat /sys/fs/cgroup/test3/cpu.stat usage_usec 3272 user_usec 0 system_usec 3272 nr_periods 0 nr_throttled 0 throttled_usec 0 (cgroupのCPUの統計情報がキーと値のペアで1行に1つずつ表示される)
書き込みを行うファイルの例としては、
このタイプのファイルに値を書き込むには、
$ echo "+io" | sudo tee /sys/fs/cgroup/cgroup.subtree_control (子cgruopでioコントローラを使えるようにする) +io $ cat /sys/fs/cgroup/test3/io.weight (io.weightの設定を表示) default 100 $ echo "default 200" | sudo tee /sys/fs/cgroup/test3/io.weight (io.weightにキーと値のペアを書き込み) default 200 $ cat /sys/fs/cgroup/test3/io.weight (値が変わった) default 200
上記の例では、default
に対する値が100
という設定がされていたところに、default 200
という文字列を書き込むことでdefault
に対する値が変更されていることがわかります。
ネストしたキー
キーに対する値が1つだけの場合は、
KEY0 SUB_KEY0=VAL00 SUB_KEY1=VAL01
KEY0 SUB_KEY0=VAL10 SUB_KEY1=VAL11
例えば、io.
は次のようになっています。
$ cat /sys/fs/cgroup/test3/io.stat 252:0 rbytes=184320 wbytes=0 rios=5 wios=0 dbytes=0 dios=0 253:0 rbytes=184320 wbytes=0 rios=5 wios=0 dbytes=0 dios=0
これは253:0
というデバイスに対するrbytes
、wbytes
、rios
、wios
、dbytes
、dios
という複数の項目名とそれに対する値を表示しています。見たとおり読み込み、
書き込む際もファイルを読んだ場合に表示されたのと同様のフォーマットで書き込みます。例えばIOの制限値を設定するio.
ファイルには次のように書き込みます。
$ cat /sys/fs/cgroup/test3/io.max (test3 cgroupのio.maxは何も設定されていない) $ echo "253:0 riops=200 wiops=200" | sudo tee /sys/fs/cgroup/test3/io.max (読み書きのIOPSを200に制限する) 253:0 riops=200 wiops=200 $ cat /sys/fs/cgroup/test3/io.max 253:0 rbps=max wbps=max riops=200 wiops=200 (読み書きのIOPSが200に設定されている)
上の例では、253:0
というデバイスに対する読み書きのIOPSriops
とwiops
)200
に設定しています。明示的に設定していない読み書きバイト数はデフォルトである制限なしmax
)
ちなみに253:0
はデバイスに対する/dev/
です。
$ ls -l /dev/vda brw-rw---- 1 root disk 252, 0 Mar 11 12:57 /dev/vda
上の例で設定した値を削除したい場合は、max
に設定すれば削除されます。
$ echo "253:0 riops=max wiops=max" | sudo tee /sys/fs/cgroup/test3/io.max 253:0 riops=max wiops=max (制限を削除するためにデフォルトのmaxを設定する) $ cat /sys/fs/cgroup/test3/io.max $ (設定の行自体が削除され、何も設定されていない状態に戻った)
デフォルト値の変更
ここまでで説明したインターフェースファイルのうち、io.
の場合がそのようなケースに該当します。
このデフォルト値の設定についても紹介しておきましょう。
先の例ではio.
を紹介しましたが、io.
ファイルを使います
io.
ファイルを使うためには、test3
cgroupを引き続き使います。Ubuntu 21.io.
はcgroup内にはありません。bfq
モジュールをロードしましょう。
$ sudo modprobe -v bfq (bfqモジュールをロードする) insmod /lib/modules/5.13.0-35-generic/kernel/block/bfq.ko $ ls /sys/fs/cgroup/test3/io.bfq* /sys/fs/cgroup/test3/io.bfq.weight (io.bfq.weightファイルが出現)
bfq
モジュールをロードしたので、io.
ファイルが出現しました。
さらに準備を続けます。ここで例として使用している筆者の環境は、/dev/
と/dev/
があります。この両方のIOスケジューラがどうなっているかを確認します。
$ cat /sys/block/vda/queue/scheduler
[mq-deadline] bfq none
$ cat /sys/block/vdb/queue/scheduler
[mq-deadline] bfq none
(/dev/vda,vdbそれぞれのスケジューラの確認)
上記のようにmq-deadline
が選択されていますbfq
を使うように設定してみます。
$ echo bfq | sudo tee /sys/block/vda/queue/scheduler bfq (IOスケジューラの変更) $ echo bfq | sudo tee /sys/block/vdb/queue/scheduler bfq (IOスケジューラの変更) $ cat /sys/block/vd?/queue/scheduler mq-deadline [bfq] none mq-deadline [bfq] none (bfqに変更された)
両方ともbfq
に変更されました。ここまでの準備を行わないと、io.
ファイルにデフォルト値以外を設定できません。
さて準備は済みましたので、io.
の中身を見てみましょう。
$ cat /sys/fs/cgroup/test3/io.bfq.weight default 100
デフォルト値が変更できる場合、default
という文字列が使われます。値は、100
が設定されています。
このデフォルト値を変更するには、"default (設定したい値)"
のようなキーと値の組を渡します。
$ echo "default 200" | sudo tee /sys/fs/cgroup/test3/io.bfq.weight (デフォルト値を200に変更) default 200 $ cat /sys/fs/cgroup/test3/io.bfq.weight default 200 (変更された)
このようにデフォルト値だけが設定されている場合は、
さて、/dev/
をデフォルト値から値を変更してみましょう。この場合はネストしたキーのところで紹介したように、/dev/
の
$ echo "252:16 300" | sudo tee /sys/fs/cgroup/test3/io.bfq.weight 252:16 300 (/dev/vdbの設定値を300に変更する) $ cat /sys/fs/cgroup/test3/io.bfq.weight default 200 252:16 300 (300に変更された)
このように新しい行が追加され、/dev/
を表す252:16
というキーに対して300
という値が設定されています。
このように設定した値をデフォルト値に戻すにはどうすれば良いでしょう? やってみましょう。
$ echo "252:16 default" | sudo tee /sys/fs/cgroup/test3/io.bfq.weight 252:16 default $ cat /sys/fs/cgroup/test3/io.bfq.weight default 200
このように、default
という値を書き込みます。すると、252:16 300
という行が消えて、
設定する値をデフォルト値に変更するためにインターフェースファイルに書き込むときは、default
を使います。しかし、default
と書かれた行は出現しません。
まとめ
今回は、
機能の説明というより、
実は、