cgroups ( control groupsの略)は、リソースの使用(CPU、メモリ、ディスクI/Oなど)を制限、管理、分離するLinuxカーネルの機能です[ 1 ]:§プロセスの集合のコントローラ。
Googleのエンジニアは、2006 年に「プロセス コンテナ」という名前でこの機能の開発に着手しました。[ 2 ] 2007 年後半には、 Linux カーネルのコンテキストで「コンテナ」という用語が複数の意味を持つことによる混乱を避けるため、名称が「コントロール グループ」に変更され、コントロール グループ機能は2008 年 1 月にリリースされたカーネル バージョン 2.6.24 でLinux カーネルのメインラインに統合されました。 [ 3 ]それ以降、開発者はカーネル自身のメモリ割り当て、[ 4 ] netfilterファイアウォール、[ 5 ] OOMキラー、[ 6 ]およびその他多くの部分のコントローラーを追加しました。
cgroup の歴史における大きな変更点は、cgroup v2です。これは、元の cgroup (現在は「v1」と呼ばれています) にあった複数のプロセス階層の使用とスレッドの区別機能を削除しています。[ 1 ] : § v1 の問題と v2 の根拠単一の統合階層に関する作業は、2014 年に、他のユーザーがまだ使用していないすべてのコントローラを保持する場所として v1 のダミー階層を再利用することから始まりました。[ 7 ] cgroup v2 は Linux カーネル 4.5 (2016 年) にマージされました。[ 8 ]
cgroupsには2つのバージョンがあり、システム内で共存させることができます。
cgroupsの設計目標の一つは、単一プロセスの制御(例えばniceコマンドの使用)から、完全なオペレーティングシステムレベルの仮想化(例えばOpenVZ、Linux-VServer、LXCなどが提供するもの)まで、さまざまなユースケースに対して統一されたインターフェースを提供することです。cgroupsは以下の機能を提供します。

コントロール グループ (cgroup と略記) は、同じ基準で束縛され、一連のパラメータまたは制限に関連付けられたプロセスの集合です。これらのグループは階層化することができ、各グループは親グループから制限を継承します。カーネルは、cgroup インターフェイスを介して複数のコントローラ (サブシステムとも呼ばれる) へのアクセスを提供します。[ 3 ]たとえば、「memory」コントローラはメモリの使用を制限し、「cpuacct」は CPU の使用を記録します。
対照群は様々な方法で使用できます。
cgcreate、、cgexecなどのツールを使用して、その場でグループを作成および管理しますcgclassify(からlibcgroup)。Linuxカーネルのドキュメントには、コントロールグループバージョン1 [ 21 ]とバージョン2 [ 1 ]の設定と使用に関する技術的な詳細が記載されています。
cgroup のどちらのバージョンも、擬似ファイルシステム ( cgroupv1 の場合は 、cgroup2v2 の場合は ) を介して動作します。すべてのファイルシステムと同様に、任意のパスにマウントできますが、一般的な慣習として、いずれかのバージョン (通常は v2) をsysfsのデフォルトの場所/sys/fs/cgroupの下にマウントします。前述のように、2 つの cgroup バージョンを同時にアクティブにすることができます。これは、ファイルシステムが異なるパスにマウントされている限り、ファイルシステムにも適用されます。[ 21 ] [ 1 ]以下の説明では、v2 階層が にある設定を想定しています。v1 階層が必要な場合は、別の場所にマウントされます。/sys/sys/fs/cgroup
初期化時、cgroup2には最上位の制御グループ以外には、定義された制御グループが存在しないはずです。つまり、/sys/fs/cgroupディレクトリは存在せず、システム全体を制御するファイルのみが存在するはずです。この時点で、ls /sys/fs/cgroupあるシステムで以下のコマンドを実行すると、次のような出力が表示されるはずです。
cgroup.controllerscgroup.max.depthcgroup.max.descendantscgroup.pressurecgroup.procscgroup.statcgroup.subtree_controlcgroup.threadscpu.pressurecpuset.cpus.effectivecpuset.cpus.isolatedcpuset.mems.effectivecpu.statcpu.stat.localio.cost.modelio.cost.qosio.pressureio.prio.classio.statirq.pressurememory.numa_statmemory.pressurememory.reclaimmemory.statmemory.zswap.writebackmisc.capacitymisc.currentmisc.peakこれらのファイルは、それらを処理するコントローラに応じて命名されます。たとえば、cgroup.*cgroup システム自体を扱い、 memory.*メモリ サブシステムを扱います。例: システム内のどこからでもカーネルに 1 ギガバイトのメモリを要求するには、 を実行しますecho "1G swappiness=50" > /sys/fs/cgroup/memory.reclaim。[ 1 ]
サブグループを作成するには、既存のグループ(最上位グループを含む)の下に新しいディレクトリを作成するだけです。このグループで使用可能なコントロールに対応するファイルは自動的に作成されます。[ 1 ]例えば、以下のコマンドを実行すると、mkdir /sys/fs/cgroup/example; ls /sys/fs/cgroup/example上記とほぼ同じファイルリストが生成されますが、いくつかの顕著な変更点があります。あるシステム例では、以下のファイルが追加されます。
cgroup.eventscgroup.freezecgroup.killcgroup.typecpu.idlecpu.maxcpu.max.burstcpu.pressurecpu.uclamp.maxcpu.uclamp.mincpu.weightcpu.weight.nicememory.currentmemory.eventsmemory.events.localmemory.highmemory.lowmemory.maxmemory.minmemory.oom.groupmemory.peakmemory.swap.currentmemory.swap.eventsmemory.swap.highmemory.swap.maxmemory.swap.peakmemory.zswap.currentmemory.zswap.maxpids.currentpids.eventspids.events.localpids.maxpids.peakこれらの変更は予想外ではありません。なぜなら、一部の制御や統計はプロセスのサブセットに対してのみ意味を持つからです(たとえば、nice レベルは、システムの残りの部分に対するプロセスの CPU 優先度です)。[ 1 ]
プロセスは、に書き込むことによってサブグループに割り当てられます。プロセスが属するcgroupは、同じファイルを読み取ることで確認できます。[ 1 ]/proc/<PID>/cgroup
systemdに基づくシステムでは、systemd によって直接的または間接的に起動されるすべてのプロセスをサブグループの下にカプセル化するために、サブグループの階層が事前に定義されています。これは、systemd がプロセスを管理する方法のまさに基本です。これらのグループの命名法の説明は、Red Hat Enterprise Linux 7 マニュアルに記載されています。[ 22 ] Red Hat は、プロセスを別の cgroup で実行させる systemd サービス ファイルの作成に関するガイドも提供しています。[ 23 ]
systemd-cgtop[ 24 ]コマンドを使用すると、リソース使用量に基づいて上位のコントロール グループを表示できます。
v2 を搭載したシステムでは、v1 をマウントして、 v2 で使用されていないコントローラにアクセスさせることができます。ただし、最新のシステムでは通常、使用中のコントローラはすべて v2 に配置されているため、階層を作成しても v1 で使用できるコントローラはまったくありません。v2 からコントローラの使用をすべてクリアして v1 に渡すことは可能ですが、システムが起動して実行された後に階層間でコントローラを移動するのは面倒で推奨されません。[ 1 ]
cgroupsの再設計は2013年に開始され、[ 25 ] Linuxカーネルのバージョン3.15と3.16によって追加の変更が加えられました。[ 26 ] [ 27 ] [ 28 ]
以下の変更点は、カーネル4.5/4.6以前、つまりcgroups-v2が追加された時点に関するものです。言い換えれば、cgroups-v1がどのように変更されたかを説明していますが、そのほとんどはv2にも引き継がれています(v1とv2は同じコードベースを共有しているため)。
厳密にはcgroupsの機能の一部ではありませんが、Linuxカーネルの関連機能として名前空間分離があります。これは、プロセスグループが分離され、他のグループのリソースを「参照」できないようにする機能です。例えば、PID名前空間は、各名前空間内でプロセス識別子を個別に列挙します。また、マウント、ユーザー、UTS(Unixタイムシェアリング)、ネットワーク、SysV IPCの名前空間も利用可能です。
名前空間は「unshare」コマンドまたはシステムコール、あるいは「clone」システムコールの「new」フラグによって作成されます。[ 34 ]
cgroupsの開発初期段階で、名前空間と制御グループを統合するために「ns」サブシステムが追加されました。「ns」cgroupがマウントされると、各名前空間はcgroup階層内に新しいグループも作成しました。これは実験的な試みでしたが、後にcgroups APIには不向きであると判断され、カーネルから削除されました。
Linuxの名前空間は、ベル研究所のPlan 9で広く使われていたより一般的な名前空間機能に触発されたものである。[ 35 ]
Kernfs は、2014 年 3 月に Linux カーネル バージョン 3.14 で導入され、主な開発者は Tejun Heo 氏です。[ 36 ]独立した kernfs の主な動機の 1 つは、cgroups ファイルシステムです。Kernfs は基本的に、 sysfs のロジックの一部を独立したエンティティに分離することによって作成され、これにより、他のカーネル サブシステムがデバイスの接続と切断、動的な作成と削除、その他の属性の処理を備えた独自の仮想ファイルシステムを実装することが容易になります。これは cgroups の使用方法には影響しませんが、コードの保守を容易にします。[ 37 ]
カーネルメモリ制御グループ(kmemcg ) はLinux カーネルのメインライン2013 年2 月 18 日( 18-02-2013 ))に統合されました。 [ 38 ] [ 39 ] [ 4 ] kmemcg コントローラは、カーネルが自身の内部プロセスを管理するために使用できるメモリの量を制限できます。
グループごとのネットフィルタ設定のサポートは2014年に追加された。[ 5 ]
統合階層は2014年に追加された。v1のダミー階層を再利用して、まだ他のコントローラーで使用されていないすべてのコントローラーを保持する。この変更されたダミー階層は、v2で唯一利用可能な階層となる。[ 7 ]
v1とは異なり、cgroup v2は単一のプロセス階層のみを持ち、スレッドではなくプロセスを区別します。
Linuxカーネル4.19(2018年10月)では、cgroupのOOMキラー実装に対する認識が導入され、cgroupを単一の単位として終了させる機能が追加され、ワークロードの整合性が保証されるようになりました。[ 6 ]
CoreOS、Docker(2013年)、Hadoop、Jelastic、Kubernetes、[ 40 ] lmctfy(Let Me Contain That For You)、LXC(Linux Containers)、systemd、MesosおよびMesosphere、[ 40 ] HTCondor、Flatpakなど、さまざまなプロジェクトがcgroupsをベースとして使用しています。
主要なLinuxディストリビューションもこれを採用しており、例えばRed Hat Enterprise Linux (RHEL) 6.0は2010年11月に採用し、メインラインLinuxカーネルに採用される3年前のことである。[ 41 ]
2019年10月29日、FedoraプロジェクトはFedora 31をCgroupsV2をデフォルトで使用するように変更しました。[ 42 ]
この文書で参照されているセクション:
汎用的すぎると考えられました。このコードはコンテナ ソリューションの重要な部分ですが、全体のごく一部にすぎません。そのため、コンテナは「コントロール グループ」(または「cgroups」)に名前が変更され、2.6.24 に統合されました。