Dockerの核となる原則であるCgroupの詳細な説明

Dockerの核となる原則であるCgroupの詳細な説明

カーネル内の強力なツール cgroup は、NameSpace によって分離されたリソースを制限できるだけでなく、リソースの重みを設定したり、使用量を計算したりすることもできます。

cgroupとは

cgroupのフルネームはコントロールグループです

コントロール グループ: コントロール グループは Linux カーネルに統合されています。コントロール グループはプロセス (タスク) をグループにまとめ、グループの権限を設定し、プロセスを制御します。これは、ユーザーとグループの概念として理解できます。ユーザーは、所属するグループの権限を継承します。

cgroupsはLinuxカーネルのメカニズムです。このメカニズムは、特定の動作に応じて一連のタスクとサブタスクを統合または分離し、さまざまなレベルのリソース分割に応じて統一されたリソース制御のフレームワークを実装できます。cgroupは、CPU、メモリ、IOなど、プロセスに必要な物理リソースを制御、制限、分離することができ、コンテナ仮想化の最も基本的な保証を提供します。これは、一連のdocker仮想化を構築するための管理ツールです。

開発中のcgroupの特徴

API: 実装管理

cgroup管理はスレッドを管理できる

すべてのスレッド機能はサブシステムによって統一的に管理されます

子プロセスと親プロセスは同じ cgroup 内にあるため、親プロセスのみを制御する必要があります。

cgroupの役割

cgroup カーネルはフックを通じてプロセス リソースを管理し、単一プロセスのリソース制御からオペレーティング システム レベルの仮想カードへの移行のための統一されたインターフェイスを提供します。

Cgroup は次の 4 つの機能を提供します。

  1. リソース制御: cgroup はプロセス グループを通じてリソースの合計量を制限します。たとえば、プログラムがメモリを使用する場合、ホスト上でプログラムが使用できるメモリの量に制限を設定する必要があります。
  2. 優先度の割り当て: ハードウェアの重み値を使用します。 2つのプログラムがCPUの読み取りプロセスを必要とする場合、どちらが先でどちらが後かを制御するために優先度が使用されます。
  3. リソース統計: CPU、メモリなどのハードウェア リソースの使用状況と使用時間をカウントできます。
  4. プロセス制御: プロセス グループを一時停止/再開できます。

用語集

  • タスク: システム内のプロセスを表す - PID
  • cgroup: リソース制御は、制御グループ (cgroup) 単位で実装されます。各 cgroup にはタスクが含まれます。複数の cgroup が存在し、異なるコンテンツを制限できます。グループ名を同じにすることはできません。
  • サブシステム: サブシステム。リソース スケジューリング コントローラー。具体的な制御内容。たとえば、CPU サブシステムは CPU 時間の割り当てを制御し、メモリ サブシステムは cgroup 内のメモリ使用量を制御し、ハード ディスク サブシステムはハード ディスクの読み取りと書き込みを制御します。
  • 階層: 階層ツリーは、多数の cgroup で構成されます。階層ツリーには複数の cgroup が含まれます。各階層は、バインドされたサブシステムを通じてリソースをスケジュールします。0 個以上の子ノードを含めることができます。子ノードは親ノードのプロパティを継承します。システム全体に複数の階層を含めることができます。これは論理的な概念です。

関係: cgroup には複数のタスクを含めることができ、サブシステムは cgroup 制限を制御するタイプに相当し、階層内に複数の cgroup を含めることができ、システムには複数の階層を含めることができます。

階層ツリーの4つのルール

従来のプロセス起動では、init をルート ノード (親プロセスとも呼ばれます) として使用し、子プロセスを子ノードとして作成します。また、各子ノードも新しい子ノードを作成できるため、ツリー構造が形成されます。 cgroup の構造はこれに似ています。子ノードは親ノードのプロパティを継承します。両者の最大の違いは、システムの cgroup で構成される階層ツリーが複数の存在を許容することです。プロセス モデルが init をルート ノードとして形成されるツリーである場合、cgroup モデルは複数の階層ツリーで構成されます。

階層ツリーが 1 つしかない場合、すべてのタスクがサブシステムの同じ制約を受けることになり、そのような制約を必要としないタスクに問題が生じます。

1. 1つまたは複数のサブシステムを同じ階層に接続できる

階層ツリーには、cpu_mem_cg という cgroup グループと、2 つの子ノード cg1 および cg2 があることがわかります。図に示すように、これは、cpu_mem_cg グループに、cpu と mem memory という 2 つのサブシステムが接続され、cg1 と cg2 の cpu とメモリのハードウェア リソースの使用を同時に制御することを意味します。

2. サブシステムは複数の階層に接続できますが、サブシステムが存在しない階層にのみ接続できます。

図に示すように、cpu サブシステムは最初に階層ツリー A に接続されますが、B にはすでに mem サブシステムがあるため、同時に階層ツリー B に接続することはできません。B と A の両方にサブシステムがない場合、cpu サブシステムは A と B の両方の階層ツリーに同時に接続できます。

つまり、複数の階層ツリーにサブシステムがない場合、CPU サブシステムをこれらの階層ツリーに順番に接続できます。

3. プロセス(タスク)は同じ階層内の異なるcgroupに属することはできない

システムが新しい階層を作成するたびに、新しい階層の初期化を構成するデフォルトの cgroup はルート cgroup と呼ばれます。独自の正常な階層では、タスクはこの階層の 1 つの cgroup にのみ存在できます。つまり、階層内に 2 つの同一のタスクが存在することはできませんが、異なる階層内の他の cgroup には存在できます。

階層ツリー cgroup 内のタスクを階層ツリー内の別の cgroup に追加する場合は、以前のタスクが配置されている cgroup から削除されます。

上記の例に示すように:

階層 A の cg1 に httpd が追加され、その pid は 58950 です。この時点では、この httpd プロセスを cg2 に配置することはできません。そうしないと、cg1 の httpd プロセスが削除されます。ただし、階層 B の cg3 コントロール グループに配置することはできます。

実は、これはプロセスの競合を防ぐためです。例えば、階層ツリー A の cg1 に httpd プロセスがあります。このとき、cg1 の CPU 使用率制限は 30%、cg2 の CPU 使用率制限は 50% です。cg2 に httpd プロセスを追加すると、httpd の CPU 使用率制限に競合が発生します。

4. 新しくフォークされた子プロセスは、初期状態では親プロセスと同じcgroupに属します。

プロセス タスクによって開かれた新しい子プロセス (child_task) は、デフォルトでは元のタスクと同じ cgroup にありますが、child_task は階層ツリー内の他の異なる cgroup に移動できます。

フォークが完了した時点では、親プロセスと子プロセスは完全に独立している。

図に示すように、誰かが httpd58950 プロセスにアクセスすると、別の子プロセス httpd58951 がフォークされます。このとき、デフォルトでは、httpd58951 と httpd58950 は両方とも cg1 にあり、それらの関係も親子プロセスです。httpd58951 は cg2 に移動することができ、この時点でそれらの関係が変更され、両方とも独立したプロセスになります。

サブシステム

サブシステムは具体的に何を制御できるのでしょうか?

以下の手順で確認します

[root@localhost ~]# yum -y libcgroup-toolsをインストールします
このツールをインストールした後、cgroupコマンドを使用して表示できます。

システム内のすべてのcgroupコントロールグループを一覧表示します

[root@localhost ~]# lscgroup
ネット_cls、ネット_prio:/
冷凍庫:/
ヒューゲットlb:/
CPU、CPUacct:/
cpu、cpuacct:/マシン.スライス
cpu、cpuacct:/user.slice
cpu、cpuacct:/system.slice
cpu、cpuacct:/system.slice/network.service
cpu、cpuacct:/system.slice/docker.service
...

サブシステムが制御できるハードウェアを表示する

[root@localhost ~]# lssubsys -a
CPUセット
CPU、CPUacct
メモリ
デバイス
冷凍庫
ネット_cls、ネット_prio
ブルキオ
パフォーマンスイベント
巨大LB
ピッド

上記のように、対応するディレクトリ/sys/fs/cgroupがあります。

[root@localhost ~]# ll /sys/fs/cgroup/
合計 0
drwxr-xr-x. 5 ルート ルート 0 3月25日 04:50 blkio
lrwxrwxrwx. 1 ルート ルート 11 3月 25 04:50 cpu -> cpu,cpuacct
lrwxrwxrwx. 1 ルート ルート 11 3月 25 04:50 cpuacct -> cpu,cpuacct
drwxr-xr-x. 5 ルート ルート 0 3月25日 04:50 cpu,cpuacct
drwxr-xr-x. 2 ルート ルート 0 3月25日 04:50 cpuset
drwxr-xr-x. 5 ルート ルート 0 3月 25 04:50 デバイス
drwxr-xr-x. 2 ルート ルート 0 3月25日 04:50 フリーザー
drwxr-xr-x. 2 ルート ルート 0 3月25日 04:50 hugetlb
drwxr-xr-x. 5 ルート ルート 0 3月25日 04:50 メモリ
lrwxrwxrwx. 1 ルート ルート 16 3月 25 04:50 net_cls -> net_cls、net_prio
drwxr-xr-x. 2 ルート ルート 0 3月25日 04:50 net_cls、net_prio
lrwxrwxrwx. 1 ルート ルート 16 3月 25 04:50 net_prio -> net_cls、net_prio
drwxr-xr-x. 2 ルート ルート 0 3月25日 04:50 perf_event
drwxr-xr-x. 5 ルート ルート 0 3月25日 04:50 pids
drwxr-xr-x. 5 ルート ルート 0 3月25日 04:50 systemd

ディレクトリの内容はコマンドで表示されるものよりも多いことがわかります。これは、いくつかのソフトリンクファイルがあるためです。

# 次の 3 つはすべて cpu、cpuacct に属します
CPU -> CPU、CPUacct
cpuacct -> cpu、cpuacct
CPU、CPUacct
# 次の3つはすべてnet_cls、net_prioに属します
net_cls -> net_cls、net_prio
net_prio -> net_cls、net_prio
ネット_cls、ネット_prio

サブシステムが制御できるコンテンツは何を表していますか?

シリアルナンバー制限されたコンテンツ意味
1 blkio (ブロックデバイスの入出力の制限)光ディスク、ソリッドステートディスク、USB…
2 CPUタスクの CPU 使用を制御できます。
3 CPUアカウント各タスクの CPU リソース使用率に関するレポートを自動的に生成します。
4 cpuset (マルチプロセッサ物理マシン用)タスクに別の CPU を割り当てます。
5デバイス (デバイスとはキーボード、マウスなどを指します)タスクのデバイスへのアクセスを無効または有効にします。
6冷凍庫タスクの一時停止と再開を制御します。たとえば、タスクが CPU を使用できないようにすることを一時停止といいます。
7メモリタスクのメモリ使用量制限を制御し、メモリリソース使用量に関するレポートを自動的に生成します。
8パフォーマンスイベントLinux の CPU パフォーマンスやハードディスクの読み取りおよび書き込み効率の検出など、タスクに対して統一されたパフォーマンス テストを実行できます。
9ネット_cls Docker では直接使用されませんが、ネットワーク パケットにクラス識別子 (classid) をマークすることで、Linux トラフィック コントローラーが特定の cgroup から発信されたパケットを識別できるようになります。

注意: 今のところ、コンテナ ハード ディスクのサイズを制限できるツールはありません。ハード ディスクの読み取りと書き込みの頻度のみを制限できます。

cgroupsの仕組み

cgroup の CPU 制御のタスク ファイルを確認します。このファイルには、プロセスの CPU の制御が保存されています。CPU を制御するプロセスを追加する場合は、他のハードウェア リソースの制御も含めて、プロセスの pid をタスク ファイルに追加するだけです。

[root@localhost ~]# cat /sys/fs/cgroup/cpu/tasks 
1
2
4
5
6
7
8
9
...
68469
68508
68526
68567

実稼働環境では、カーネル内にあるため自動的に増加します。

cgroup の実際の動作原理はフックです。cgroup の実装は、基本的にシステム プロセスをフックすることです。タスク プロセスの実行中に特定のリソースが設計されると、フックに接続されたサブシステムがトリガーされ、リソース検出が実行されます。最後に、対応するテクノロジを使用して、さまざまなリソース カテゴリに応じてリソースを制限し、優先順位を割り当てます。

フックはどのように実装されていますか?

簡単に言うと、Linux でタスク プロセスを管理するためのデータ構造は、cgroup 内の各タスクにキーワードを設定し、そのキーワードをポインターと呼ばれるフックにポイントします。

タスクが 1 つのポインタ構造のみに対応する場合、ポインタ構造は複数のタスクで使用できます。

ポインタが固有のポインタ データの内容を読み取ると、タスクがトリガーされ、リソース制御を実行できるようになります。

実際の使用では、ユーザーはマウントを使用してcgroupコントロールグループをマウントする必要があります。

ディレクトリでは、例えばhttpdプログラムのpid番号が69060であることがわかります。

[root@localhost ~]# yum -y httpd^C をインストールします
[root@localhost ~]# systemctl start httpd^C
[root@localhost ~]# netstat -anput | grep 80
tcp6 0 0 :::80 :::* 69060/httpdをリッスン

pid ディレクトリ内のマウント ファイルを確認します。このファイルには、多数の cgroup マウントが含まれています。

各 cgoup の背後にあるディレクトリ ( /sys/fs/cgroup/cpu,cpuacctなど) を確認できます。これは、 httpd プロセスが CPU 使用率によって制限されていることを意味します。ファイルには、 blkio/perf_event/memoryなどのハードウェア リソース制御を含む、同様のマウント項目が多数あります。

[root@localhost ~]# cat /proc/69060/mounts
ルートfs / ルートfs rw 0 0
/dev/mapper/centos-root / xfs rw、seclabel、relatime、attr2、inode64、noquota 0 0
devtmpfs /dev devtmpfs rw、seclabel、nosuid、サイズ=914476k、nr_inodes=228619、モード=755 0 0
tmpfs /dev/shm tmpfs rw、seclabel、nosuid、nodev 0 0
devpts /dev/pts devpts rw、seclabel、nosuid、noexec、relatime、gid=5、mode=620、ptmxmode=000 0 0
mqueue /dev/mqueue mqueue rw、seclabel、relatime 0 0
hugetlbfs /dev/hugepages hugetlbfs rw、seclabel、relatime 0 0
...
cgroup /sys/fs/cgroup/systemd cgroup rw、seclabel、nosuid、nodev、noexec、relatime、xattr、release_agent=/usr/lib/systemd/systemd-cgroups-agent、name=systemd 0 0
cgroup /sys/fs/cgroup/net_cls、net_prio cgroup rw、seclabel、nosuid、nodev、noexec、relatime、net_prio、net_cls 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw、seclabel、nosuid、nodev、noexec、relatime、freezer 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw、seclabel、nosuid、nodev、noexec、relatime、hugetlb 0 0
cgroup /sys/fs/cgroup/cpu、cpuacct cgroup rw、seclabel、nosuid、nodev、noexec、relatime、cpuacct、cpu 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw、seclabel、nosuid、nodev、noexec、relatime、cpuset 0 0
cgroup /sys/fs/cgroup/devices cgroup rw、seclabel、nosuid、nodev、noexec、relatime、devices 0 0
cgroup /sys/fs/cgroup/memory cgroup rw、seclabel、nosuid、nodev、noexec、relatime、memory 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw、seclabel、nosuid、nodev、noexec、relatime、blkio 0 0
cgroup /sys/fs/cgroup/pids cgroup rw、seclabel、nosuid、nodev、noexec、relatime、pids 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw、seclabel、nosuid、nodev、noexec、relatime、perf_event 0 0
...

これは、cgroup が mount によって制御される方法です。すべてのプログラムがこのようになっています。サブシステム上のすべてのシステムがファイルをマウントした後、権限管理やサブファイルシステムなど、オペレーティングシステムのように cgroup と階層ツリーを管理できます。cgroup ファイルシステムに加えて、カーネルは cgroup アクセスに対して他の操作を提供しません。cgroup を操作する場合は、mount を使用して cgroup 制御グループにハングする必要があります。

リソース制御操作

各ハードウェア リソースを制御する方法を知る必要があります。

のように:

cgroupグループのcpuディレクトリ内の各項目の具体的な意味は、cpuの具体的な制御の詳細です。

[root@localhost ~]# cd /sys/fs/cgroup/cpu
[root@localhost cpu]# ls
cgroup.clone_children cpuacct.stat cpu.cfs_quota_us cpu.stat system.slice
cgroup.event_control cpuacct.usage cpu.rt_period_us machine.slice タスク
cgroup.procs cpuacct.usage_percpu cpu.rt_runtime_us notification_on_release user.slice
cgroup.sane_behavior cpu.cfs_period_us cpu.shares リリースエージェント

これらの具体的な使用方法については、次の記事で一つずつ説明します。

Docker コマンドラインの制限

-c/--cpu-shares: CPU 優先度を制限 -m/--memory: メモリ使用量を制限 --memory-swap: メモリ + スワップのサイズを制限 --blkil-weight
bps/iops
--デバイス読み取りbps
--デバイス書き込みbps
--デバイス読み取りIOPS
--デバイス書き込みIOPS

具体的な使用法: CPU、メモリ、blkio

cgroupのディレクトリ構造は次のようになります

/sys/fs/cgroupはすべてのプロセスのハードウェアリソース制御を保存します

特定のハードウェアリソースのデフォルトの非Dockerプロセス制御は/sys/fs/cgroup/{cpu,memory,blkio...}/ fs/cgroup/{cpu,memory,blkio...}/ディレクトリに保存されます。DockerプロセスIDはこれらのディレクトリには存在しません。

/sys/fs/cgroup/cpu/docker/ディレクトリには、ホスト内の docker プロセス制御が保存されます。

dockerによって生成されたコンテナの制御は/sys/fs/cgroup/cpu/docker/容器id/ディレクトリに保存されます。

Docker のコア原則である Cgroup の詳細説明はこれで終了です。Docker のコア原則についてさらに詳しく知りたい方は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Docker基盤技術の適用に関する詳細な説明 名前空間Cgroup
  • docker cgroupリソース監視の詳細な説明
  • cgroups を使用して Docker コンテナのリソース使用量を制限する方法の詳細な説明
  • この記事は、Dockerにおけるcgroupの具体的な使用法を徹底的に理解するのに役立ちます。

<<:  IMG での UserMap の使用例

>>:  CSSを使用して複数の画像を中央に水平に表示する方法

推薦する

JavaScriptはボタンをクリックして4桁のランダムな検証コードを生成します

この記事の例では、ボタンをクリックすることで4桁のランダムな検証コードを生成するjsの具体的なコード...

Ubuntu 16.04 にソースコードから Mininet をインストールする

ミニネットMininet は軽量のソフトウェア定義ネットワークおよびテスト プラットフォームです。軽...

Ubuntu 20.04 では、隠し録音ノイズ低減機能が有効になります (推奨)

最近、 Ubuntu 20.04でkazamを使用して録音しているときに、問題が見つかりました。シス...

JavaScript ループトラバーサルの 24 種類のメソッドをすべてご存知ですか?

目次序文1. 配列走査法1. 各() 2. マップ() 3. 〜のために4. フィルター() 5. ...

HTML チュートリアル: 画像のサイズ、配置、間隔、境界線の属性を変更する方法

画像タグ: <img> ページに画像を挿入するには、「src」属性を持つ「img」タグを...

優れた登録プロセスの手順

ウェブサイトにとって、これは最も基本的な機能です。それでは、登録プロセスに含まれる手順を見てみましょ...

Reactはグローバル箇条書きボックスメソッドをカプセル化します

この記事の例では、Reactカプセル化グローバルポップアップボックスの具体的なコードを参考までに共有...

VueはWebSocketを使用してチャット機能をシミュレートします

この効果は、2つのブラウザが互いにシミュレートしていることを示しています 1. シミュレートされたノ...

Vueプロジェクトが完了した後にプロジェクトを最適化する方法の例

目次1. 開発モードとリリースモードに異なるパッケージエントリポイントを指定する2. 外部CDNリソ...

HTML に埋め込まれた MP4 形式のビデオが再生できないのはなぜですか?

次のコードは、私の test.html にあります。ビデオは、c:\test.html などの絶対パ...

JavaScript es6 の新しい配列メソッドの詳細な説明

目次1. 各() 2. arr.filter() 3. arr.every() 4. arr.map...

MySQL 8.0.18 のインストールと設定方法のグラフィックチュートリアル (Windows 10 版)

この記事は、参考のためにMySQL 8.0.18のインストールと設定のグラフィックチュートリアルを記...

Vue.js でフォントを読み込む正しい方法

目次font-faceでフォントを正しく宣言するフォントをプリロードするフォントをホストするにはli...

構造とプレゼンテーションの分離を理解するためのWeb標準の学習

Web 標準について議論するときに必ず話題になるのは、構造とプレゼンテーションを分離することの重要性...