Control Group v2
以前も少し紹介していましたし、連載でも少し触れましたが、今広く (?) 使われている cgroup は色々問題があって、単一階層構造の cgroup が開発されていました。この辺りは
- Linux 3.16 から試せる cgroup の単一階層構造 (1) - TenForwardの日記
- Linux 3.16 から試せる cgroup の単一階層構造 (2) - TenForwardの日記
で紹介しました。
以前は開発中の機能だったため、マウントするときに "__DEVEL__sane_behavior" などというふざけたオプションが必要でした。(^^)
この後も順調に (?) 開発はすすみ、4.5 カーネルのリリースでついにこの機能が stable となったようで、"__DEVEL__" というプレフィックスも不要になりましたし、正式な機能で「まともなふるまい」なんてのはないだろうという話があったのかなかったのか知りませんが、名前も "Control Group v2" という名前になったようです。今までのは "v1" です。
ドキュメントは
にあります。
前に試した時は v1 にあったコントローラ (サブシステム) が全部現れていましたが、正式リリースとなった 4.5 の時点で有効なコントローラは memory, io, pid の 3 つだけのようです。
v1 の問題点のひとつに、コントローラがばらばらに実装されているため、コントローラ間の連携ができないという問題がありました。このため、blkio というブロックデバイスに対する I/O 制限を行うコントローラがあるにもかかわらず、通常のファイル I/O (の書き込み) に対する制限ができませんでした (memory と連携できていないため)。
この辺りは「第4回 コンテナ型仮想化の情報交換会@東京」で @hiro_kamezawa さんにお話頂いたので、詳細をお知りになりたい方はそちらをどうぞ。
v2 では、階層構造が単一となって、この辺りの制限ができるようになりました。昨年の LinuxCon で Heo Tejun 氏が ext2 に対応したという話をされていましたが、4.5 を見てみると ext2, ext4, btrfs に対して制限がかかるようです。
というわけで、この制限が働くのか簡単に試してみました。
kernel は 4.6-rc3、ファイルシステムは ext2 と ext4 で試しています。
かなり適当な確認なので、間違いとかあるかもしれませんので、気づいたら優しく教えてください。
v1 のおさらい
v2 を試す前に、まずは v1 の blkio コントローラのおさらいをしておきましょう。direct I/O 以外では制限がかかっていないことも確認してみました。
v1 準備
"test01" cgroup を作成して、/dev/vdb に対する 1MB/sec の読み書きの制限を設定してみました。
- cgroup 作成
# mkdir /sys/fs/cgroup/blkio/test01
- プロセスを "test01" へ登録
# echo $$ > /sys/fs/cgroup/blkio/test01/tasks
- /dev/vdbに対する制限を設定
# ls -l /dev/vdb
brw-rw---- 1 root disk 254, 16 Apr 13 06:30 /dev/vdb (デバイス番号の確認)
# echo "254:16 1048576" > /sys/fs/cgroup/blkio/test01/blkio.throttle.read_bps_device (読み込み制限)
# echo "254:16 1048576" > /sys/fs/cgroup/blkio/test01/blkio.throttle.write_bps_device (書き込み制限)
v1 を使った書き込み制限 (direct I/O)
# dd oflag=direct if=/dev/zero of=/data/testfile bs=4K count=1024 1024+0 records in 1024+0 records out 4194304 bytes (4.2 MB) copied, 4.00347 s, 1.0 MB/s
実行時に iostat を実行しました。出力の一部。
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vdb 258.59 0.00 1034.34 0 1024 vdb1 258.59 0.00 1034.34 0 1024
書き込みが 1MB/sec に制限されていますね。
v1 を使った読み込み制限 (direct I/O)
# dd iflag=direct if=/data/testfile of=/dev/null bs=4K count=1024 1024+0 records in 1024+0 records out 4194304 bytes (4.2 MB) copied, 4.0018 s, 1.0 MB/s
同様に iostat 出力の一部。
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vdb 261.22 1044.90 0.00 1024 0 vdb1 261.22 1044.90 0.00 1024 0
読み込みが 1MB/sec に制限されています。
v1 を使った書き込み制限
"oflag=direct" を指定せずに dd を実行してみると、
# dd if=/dev/zero of=/data/testfile bs=4K count=1048576 ^C636264+0 レコード入力 636264+0 レコード出力 2606137344 バイト (2.6 GB) コピーされました、 22.6348 秒、 115 MB/秒
# iostat -p vdb 1 | grep "vdb " :(略) vdb 311.00 12.00 315392.00 12 315392 vdb 339.00 12.00 344064.00 12 344064 vdb 456.57 12.12 434424.24 12 430080 vdb 389.53 4.65 351255.81 4 302080 vdb 11.00 0.00 9216.00 0 9216 vdb 39.00 8.00 33688.00 8 33688 vdb 35.00 0.00 31940.00 0 31940 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 :(略) vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 84.21 4.21 73675.79 4 69992 vdb 140.43 0.00 126012.77 0 118452 vdb 11.11 4.04 9002.02 4 8912 vdb 507.22 12.37 443455.67 12 430152 vdb 410.10 12.12 376501.01 12 372736 vdb 1.00 0.00 912.00 0 912
制限はかかっていませんね。書き込まれたらしばらく 0 の時間があり、また書き込みが再開されているのがわかります。
v1 を使った読み込み制限
"iflag=direct" を外して実行します。実行前にキャッシュクリアします。
# echo 3 > /proc/sys/vm/drop_caches (キャッシュクリア) # dd if=/data/testfile of=/dev/null bs=4K count=1024 1024+0 records in 1024+0 records out 4194304 bytes (4.2 MB) copied, 4.0036 s, 1.0 MB/s
読み込みは制限がききますね。
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vdb 8.25 1055.67 0.00 1024 0 vdb1 8.25 1055.67 0.00 1024 0
cgroup v2 の io コントローラ
v2 の準備
v2 は "cgroup2" という名前でマウントします。名前以外は以前試した「まともなふるまい」時代とあまり変わりません。
- /sys/fs/cgroup にマウント。
mount -t cgroup2 cgroup /sys/fs/cgroup/
- ルート cgroup の確認。ファイルが 3 つだけです
# ls /sys/fs/cgroup/
cgroup.controllers cgroup.procs cgroup.subtree_control - 使えるコントローラを確認
# cat /sys/fs/cgroup/cgroup.controllers
io memory pids - "memory" と "io" をサブ cgroup で使えるようにします
# cat /sys/fs/cgroup/cgroup.subtree_control (サブ cgroup で使えるコントローラ一覧の確認。デフォルトは空)
# echo "+memory +io" > /sys/fs/cgroup/cgroup.subtree_control (io と memory を追加)
# cat /sys/fs/cgroup/cgroup.subtree_control (再度確認)
io memory (登録されている) - "test01" cgroup 作成
mkdir /sys/fs/cgroup/test01 (作成)
"test01"でioとmemoryが使えるのが確認できました
# ls /sys/fs/cgroup/test01 (test01ディレクトリの確認)
cgroup.controllers io.max memory.events memory.stat
cgroup.events io.stat memory.high memory.swap.current
cgroup.procs io.weight memory.low memory.swap.max
cgroup.subtree_control memory.current memory.max
# cat /sys/fs/cgroup/test01/cgroup.controllers (test01で使えるコントローラの確認)
io memory
v2 で direct I/O 制限
まずは v1 でもちゃんと制限された direct I/O を確認しました。
まずは書き込み。
# dd oflag=direct if=/dev/zero of=/data/testfile bs=4K count=1024 1024+0 レコード入力 1024+0 レコード出力 4194304 バイト (4.2 MB) コピーされました、 4.0041 秒、 1.0 MB/秒
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vdb 261.22 0.00 1044.90 0 1024 vdb1 261.22 0.00 1044.90 0 1024
読み込み。
# dd iflag=direct if=/data/testfile of=/dev/null bs=4K count=1024 1024+0 レコード入力 1024+0 レコード出力 4194304 バイト (4.2 MB) コピーされました、 4.00393 秒、 1.0 MB/秒
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vdb 261.22 1044.90 0.00 1024 0 vdb1 261.22 1044.90 0.00 1024 0
v1 と同じく制限されています。
v2 で読み込み制限
少し大きなファイルで確認しました。
# echo 3 > /proc/sys/vm/drop_caches # dd if=/data/testfile of=/dev/null bs=4K count=1048576 ^C4605+0 レコード入力 4604+0 レコード出力 18857984 バイト (19 MB) コピーされました、 18.1077 秒、 1.0 MB/秒
iostat の出力は
# iostat -p vdb 1 | grep "vdb " vdb 30.83 2378.02 10808.93 1864321 8473984 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 7.07 630.30 0.00 624 0 vdb 8.08 1034.34 0.00 1024 0 vdb 8.00 1024.00 0.00 1024 0 vdb 8.08 1034.34 0.00 1024 0 vdb 8.00 1024.00 0.00 1024 0 vdb 8.08 1034.34 0.00 1024 0 :(略)
これは v1 と同じように制限がかかります。
v2 で書き込み制限
さて、いよいよハイライト。
# dd if=/dev/zero of=/data/testfile bs=4K count=1048576 ^C51563+0 レコード入力 51563+0 レコード出力 211202048 バイト (211 MB) コピーされました、 35.7076 秒、 5.9 MB/秒
# iostat -p vdb 1 | grep "vdb " vdb 28.16 2182.44 9794.36 1888229 8473984 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdb 36.17 144.68 0.00 136 0 vdb 1.05 0.00 842.11 0 800 vdb 1.01 0.00 517.17 0 512 vdb 1.00 0.00 508.00 0 508 vdb 1.01 0.00 783.84 0 776 vdb 3.00 0.00 1160.00 0 1160 vdb 1.00 0.00 1004.00 0 1004 vdb 1.01 0.00 1034.34 0 1024 vdb 1.01 0.00 1034.34 0 1024 vdb 1.01 0.00 1034.34 0 1024 vdb 1.01 0.00 1034.34 0 1024 vdb 0.99 0.00 1013.86 0 1024 vdb 2.02 0.00 1046.46 0 1036 vdb 2.00 0.00 1024.00 0 1024 vdb 1.01 0.00 1034.34 0 1024
落ち着くまで少し時間があるのと、一瞬 1024 以上の値が出てますが、大体きれいに 1024 (KB) で制限されています。
まとめ
とりあえずディスクへの書き込みがちゃんと制限されているっぽいです (たぶん)。