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

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

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

cgroupのタイプ

このスレッドモードが導入されたことにともない,cgroupツリー内にディレクトリとして作成するcgroupにはいくつかのタイプが定義されました。作成されたcgroupは表1のタイプのいずれかが設定されます。

表1 cgroupのタイプ

タイプ 説明
domain プロセス単位でのコントロールを行う従来のcgroup
threaded スレッド単位のコントロールを行うcgroup
domain threaded スレッド化サブツリーのroot。このcgroup配下のcgroupが"threaded"となる
domain invalid スレッド化サブツリー内でcgroupを作成した直後の"invalid"な状態

スレッド化サブツリー

スレッド化サブツリーがあるv2ツリーの様子を図で表すと図1のようになります。

図1 スレッド化サブツリー

図1 スレッド化サブツリー

通常のcgroup("cgroup A〜D")は"domain"となっており,これらのcgroupでは通常どおりプロセス単位でコントロールします。そして"cgroup T"をルートとした点線内がスレッド化サブツリーで,このサブツリー内の"cgroup T,T-a,T-b"はスレッド単位でコントロールできます。

このスレッド化サブツリー内ではスレッド単位でコントロールできるので,スレッドはサブツリー内に存在するどこのcgroupにも所属できますし,同一プロセス内のスレッドであっても異なるcgroupに所属できます。

また,v2が持つ特徴のひとつに,プロセスはツリーの末端cgroupにのみ所属できるという制約がありました。これは親子関係のあるcgroup間で内部タスクの競合が起こることを防ぐために設定された制約です。しかし,スレッド化サブツリー内ではこのような制約はありません。スレッド化サブツリー内であれば,末端であっても末端でなくても任意のcgroupでリソース制御ができますし,すでにスレッドが所属しているcgroupでcgroup.subtree_controlにスレッドコントローラを設定できます。

逆に言うとスレッドコントローラは,スレッド単位でコントロールすると同時に,親子関係にあるcgroup間に所属するタスクの競合をうまく扱えなければならないということです。

このように導入されたスレッド化サブツリーでは,v2で設定された制限が大幅に緩められているように見えますが,もちろんスレッド化サブツリーならではの制限があります。これを説明しましょう。

スレッド化サブツリー内はすべて"threaded"でなければならない

まず最初の制限は,スレッド化サブツリー内のcgroupは,ルートが"domain threaded"である以外は,すべて"threaded"なcgroupでなければなりません。

v2のデフォルトは"domain"ですので,新規にcgroupを作成した直後はスレッド化サブツリー内であっても初期状態としては"domain"として作成されます。スレッド化サブツリー内ではcgroupは"threaded"である必要がありますので,作成直後の"domain"状態では使えません。この状態が"domain invalid"の状態です。

たとえば,図1のように"cgroup T-b"に子cgroupとなる"cgroup T-c"を作ったとすると,作成直後は"domain"であり,スレッド化サブツリー内では使えない状態である"domain invalid"となります。この"domain invalid"のcgroupは"threaded"に変えることができます。

同じプロセス内のスレッドは同じスレッド化サブツリー所属でなければならない

スレッド化サブツリーはシステム上に複数存在できます。しかし,システム上にスレッド化サブツリーが複数ある場合でも,同じマルチスレッドプロセス内のスレッドは同じスレッド化サブツリーに所属している必要があります。

これは,スレッド単位でコントロールしたいプロセスを一旦スレッド化サブツリーのルートに登録して,そのプロセス内のスレッドをサブツリーに分配していくと考えるとわかりやすいでしょう。

また,この制限により,スレッドを扱わないドメインコントローラは,プロセスが"domain threaded"であるcgroupに属すると考えて処理できますので,ドメインコントローラとも共存できます。

スレッドモードに関係するファイル

cgroupは,これまでこの連載でも紹介した機能と同様に,cgroupツリー内に存在するファイルやディレクトリを操作することで設定などの制御を行います。

このうち,スレッドモードに関係するファイルを紹介しましょう。

表2 v2で使用するファイルのうちスレッドモードに関係するファイル

ファイル名 説明 出現するcgroup
cgroup.type cgroupのタイプ root以外
cgroup.threads cgroupに所属するスレッドのリスト rootを含むすべて
cgroup.type

cgroup.typeは,そのファイルが存在するcgroupが,表1で説明したcgroupタイプのうちどのタイプなのかを示します。また,cgroupのタイプを変更したい場合に,タイプを表す文字列を書き込むことでcgroupのタイプを変更します。root以外のすべてのcgroupに存在します。

# mount -t cgroup2 cgroup2 /sys/fs/cgroup/
# mkdir /sys/fs/cgroup/test01
# cat /sys/fs/cgroup/test01/cgroup.type 
domain

このように,作成したcgroupのcgroup.typeの中身を確認するとdomainであることがわかります。変更する方法は次回説明します。

cgroup.threads

cgroupに所属するスレッドIDが含まれるファイルです。rootを含むすべてのcgroupに存在します。

次のようにふたつのスレッドを持つプロセスがある場合,cgroup.procsには親となるプロセスのPIDのみが含まれており,cgroup.threadsにはcgroup.procsにも書かれていたPIDに加えて,プロセスに所属するスレッドのIDも含まれています。

# pstree -p 946
threadtest(946)─┬─{threadtest}(947)
                 └─{threadtest}(948)
# cat cgroup.procs 
946
# cat cgroup.threads 
946
947
948

上の実行例のように,v1のtasksファイルやv2のcgroup.procsと同様に所属させたいタスクのIDを書き込んだり,所属しているタスクを表示したりできます。cgroup.procsと異なるのはスレッドのIDであるTID単位で登録ができるということです。

まとめ

今回はスレッドモードの概要と,それにともない導入されたcgroupのタイプ,スレッドモードの制約,スレッドモードに関係するcgroup内のファイルについて説明しました。

今回は,スレッドモードについて次のようなことを説明しました。

  • cgroupツリーの一部にスレッドを扱えるスレッド化サブツリー(Threaded subtree)が作成できる
  • スレッドモードに対応したスレッドコントローラだけがスレッド化サブツリー内でスレッドを扱える
  • cgroupにはタイプが存在する
  • 同じプロセス内のスレッドは同一のスレッド化サブツリー内に所属している必要がある

次回は,実際にスレッド化サブツリーの操作を行っていく予定です。スレッド化サブツリーを作成し,その作成したスレッド化cgroupにプロセスやスレッドを追加したり,サブツリー内では同一プロセス内のスレッドでも別のcgroupに所属できることなど,これまで紹介してきたcgroup v2とは違う,スレッドモード独特の動きを紹介していきます。

著者プロフィール

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

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

Plamo Linuxメンテナ

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