LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術

第45回 Linuxカーネルのコンテナ機能 ― cgroupの改良版cgroup v2[6]

この記事を読むのに必要な時間:およそ 3 分

昨年12月に前回の記事を書いて以来,世の中の状況がすっかり変わってしまいました。

筆者も4月以降はほとんど会社に出勤することなく,自宅で仕事をしています。自宅の物置のように使っていたスペースを片付け,少しずついろいろなものを買い揃え,自宅でもまずまず快適な環境で仕事ができるようになりました。同様に,これを機に自宅でも快適に仕事ができるようにいろいろと買い揃えた方も多いのではないでしょうか。残念ながら,自宅の環境が快適になったからと言ってこの記事の公開ペースが速くなるということはありませんが。:-p

さて,年末に書いた記事ではケーパビリティの話を3回に渡って説明しました。今回はそのケーパビリティシリーズの前に紹介していたcgroup v2の話題に戻って,その機能を紹介していきたいと思います。

cgroup v2とCPUコントローラ

この連載の第37回で書いたように,cgroup v1は自由度が高い反面,制約も多かったため,結局自由度の高さを活かすことができませんでした。

そこで,cgroup v1(以降v1)が持っていた問題点を解決するためにcgroup v2(以降v2)の開発が始まり,v2は4.5カーネル(2016年3月)で正式な機能となりました。

v2が4.5カーネルで正式機能になったとはいえ,リソースコントロールを行う対象としては重要な機能のひとつであるCPUコントローラが使えませんでした。4.5カーネルがリリースされた時点のカーネルに付属していたv2のドキュメントにはCPUコントローラに関する記載がありました。しかし,⁠CPUコントローラに対するインターフェースはまだマージされていない」という注意書きがあり,機能としてはマージされていませんでした。

これは,v1が持っていた問題点を解決すべく定められたv2の仕様が,スケジューラの開発者に受け入れられなかったためです(※1)

連載の第37回で説明したとおり,v2が持つ重要な特徴のひとつに,cgroupでコントロールする対象をプロセス単位にしたことが挙げられます。

この理由は,v1ではスレッド単位でのコントロールを行っていたにもかかわらず,ほとんどのコントローラではスレッド単位で制御を行う意味なかったためです。このため,v2では制御の単位をコントローラ全体で意味のあるプロセスとしました。

しかし,コントローラの中にはスレッド単位で制御を行う意味があるコントローラがありました。これがCPUコントローラです。スケジューラの観点から見ると,制御の単位はスレッドであり,プロセスという粗い単位で制御を行っても意味がないとさえ言えたわけです。

また,同じく第37回で説明した「プロセスが所属できるのは末端のcgroupのみ」という機能についてもCPUコントローラにとっては邪魔な制限でした。多くのコントローラではcgroupにプロセスと子cgroupの両方が所属した場合,cgroupに所属するタスクと子cgroupに所属するタスクの競合問題が発生しました。この問題に対するコントローラ側のサポートを簡単にするために,末端のcgroupにしかタスクが所属できなくなったのですが,これはCPUコントローラにとっては解決できる問題でした。

このようなv2が持つ特徴は,v2で一番重要な特徴である「単一階層構造」を取るために必要なことでした。単一の階層なのですから,あるcgroupに所属するタスクはいろいろなコントローラから同時に制御を受ける可能性があるためです。

※1)
この問題はかなり長く議論されたようで,cgroupのメンテナであるTejun Heo氏が議論の途中で状況をまとめる文書をリリースしたほどです

スレッドモード

v2はデフォルトではプロセス単位でコントロールします。このプロセス単位でコントロールを行う動作は変えず,先に書いたような問題を解決する方法が導入されました。

これが今回紹介する,スレッド単位でコントロールしたいコントローラと,プロセス単位でコントロールを行うv2の仕様が両立できるように導入したスレッドモードです。スレッドモードは第41回で紹介したとおり,4.14カーネルで導入されました。

スレッドモードでは,スレッドモードに対応したコントローラはスレッド単位でコントロールできます。スレッド単位で制御を行いたいコントローラと,v2デフォルトのプロセス単位でのコントロールするcgroupとの両立をするために,cgroupツリー内の特定のcgroup配下のツリー(サブツリー)でスレッドが扱えるようになりました。このようにスレッド単位でコントロールができるサブツリーをスレッド化サブツリー(Threaded subtree)と呼びます。

スレッドコントローラ

スレッドモードは,スレッドでリソース制御が行えるコントローラのために作られたモードです。このため,スレッドモードに対応したコントローラだけがスレッド化サブツリー内で使えます。このようにスレッドモードに対応したコントローラをスレッドコントローラ(Threaded controllers)と呼びます。

執筆時点の5.7カーネル内に存在するスレッドコントローラは次のコントローラです。

  • cpu
  • cpuset
  • perf_event
  • pids

これ以外のコントローラはプロセス単位でのリソース制御のみに対応しておりドメインコントローラ(Domain controllers)と呼びます。

著者プロフィール

加藤泰文(かとうやすふみ)

2009年頃にLinuxカーネルのcgroup機能に興味を持って以来,Linuxのコンテナ関連の最新情報を追っかけたり,コンテナの勉強会を開いたりして勉強しています。英語力のない自分用にLXCのmanページを日本語訳していたところ,あっさり本家にマージされてしまい,それ以来日本語訳のパッチを送り続けています。

Plamo Linuxメンテナ

Twitter:@ten_forward
技術系のブログ:http://tenforward.hatenablog.com/