この記事は、Dockerにおけるcgroupの具体的な使用法を徹底的に理解するのに役立ちます。

この記事は、Dockerにおけるcgroupの具体的な使用法を徹底的に理解するのに役立ちます。

序文

プロセスは、システム内の CPU、メモリ、ディスクなどのコンピューティング リソースまたはストレージ リソースを比較的任意に使用します。プロセス リソースの使用率を制限し、プロセス リソースの使用状況を追跡したいと考えています。これにより、プロセスを均一にグループ化し、グループに基づいてリソースを監視および制御するために使用される cgroup の出現が可能になります。

cgroupとは

Linux CGroup (Linux Control Group) は、実際には Linux カーネルの機能です。これは、プロセスをグループ別に管理するための Linux のメカニズムです。これは、2006 年に Google のエンジニアである Paul Menage 氏と Rohit Seth 氏によって最初に開始され、当初はプロセス コンテナと名付けられました。 2007 年以降、コンテナが導入されると、混乱を避けるために cgroup に名前が変更され、カーネル バージョン 2.6.24 に統合されました。
ユーザー レベルの観点から見ると、cgroup テクノロジはシステム内のすべてのプロセスを独立したツリーに編成します。各ツリーにはシステムのすべてのプロセスが含まれます。ツリーの各ノードはプロセス グループであり、各ツリーは 1 つ以上のサブシステムに関連付けられています。ツリーは主にプロセスをグループ化するために使用され、サブシステムはこれらのグループを操作するために使用されます。

cgroupの構成

Cグループは主に以下の2つの部分から構成されます

  • サブシステム: サブシステムはカーネル モジュールです。cgroup ツリーに関連付けられると、ツリー ノードに対して特定の操作を実行します。このサブシステムは、各プロセス グループのリソースをスケジュールまたは制限するために主に使用されるため、「リソース コントローラー」と呼ばれることがよくありますが、この記述は完全に正確ではありません。perf_event サブシステムのように、監視やステータスの観察を行うためだけにプロセスをグループ化することもあるためです。
  • 階層: 階層は cgroup ツリーとして理解できます。ツリーの各ノードはプロセス グループであり、各ツリーは複数のサブシステムに関連付けられています。ツリーには Linux システム内のすべてのプロセスが含まれますが、各プロセスは 1 つのノード (プロセス グループ) にのみ属することができます。システムには多数の cgroup ツリーが存在する可能性があり、各ツリーは異なるサブシステムに関連付けられ、プロセスは複数のツリーに属することができます。つまり、プロセスは複数のプロセス グループに属することができ、各プロセス グループが異なるサブシステムに関連付けられます。

/proc/cgroupディレクトリを表示することで、現在のシステムがサポートしているサブシステムの関連付けを確認できます。

ここに画像の説明を挿入

最初の列: サブシステム名を示します

2 番目の列: 関連付けられている cgroup ツリーの ID を示します。複数のサブシステムが同じ cgroup ツリーに関連付けられている場合、それらのフィールドは同じになります。たとえば、図の cpuset、cpu、cpuacct などです。

3 番目の列: サブシステムに関連付けられた cgroup ツリー内のプロセス グループの数、つまりツリー上のノードの数を示します。

cgroupが提供する機能

以下の機能を提供します

  • リソース制限: リソース使用制限
  • 優先順位付け: 優先度制御
  • 会計:監査または統計
  • 制御: プロセスを一時停止し、実行プロセスを再開する

一般的に、cgroupは次のことを行うために使用できます。

  • 一連のプロセス(すべてのMySQLプロセスなど)を分離し、コア制限などのリソースの使用を制限します。
  • このプロセスセットにメモリを割り当てる
  • このプロセスセットに十分な帯域幅とストレージ制限を割り当てる
  • 特定のデバイスへのアクセスを制限する

cgroupはLinuxのファイルシステムとして表示されます。次のコマンドを実行します。

ここに画像の説明を挿入

マウントが成功すると、/sys/fs の下に多くのサブシステムを含む cgroup ディレクトリがあることがわかります。たとえば、cpu、cpuset、blkio などです。
次に、/sys/fs/cgroup/cpu ディレクトリにサブディレクトリ test を作成します。この時点で、このディレクトリにはさらに多くのファイルがあることがわかります。

ここに画像の説明を挿入

cgroup 内の CPU を制限する

cgroup では、CPU 関連のサブシステムには cpusets、cpuacct、cpu が含まれます。
その中で、cpuset は主に CPU のアフィニティを設定するために使用されます。cgroup 内のプロセスを指定された CPU でのみ実行するように制限したり、指定された CPU で実行しないように制限したりできます。同時に、cpuset はメモリのアフィニティも設定できます。 cpuacct には、現在の cgroup によって使用されている CPU に関する統計が含まれています。ここでは、次の CPU についてのみ説明します。

次に、/sys/fs/cgroup/cpuの下にサブグループを作成し、このディレクトリの下のファイルリストを作成します。

ここに画像の説明を挿入

cpu.cfs_period_us は期間の長さを設定するために使用され、cpu.cfs_quota_us は設定された期間の長さ内で現在の cgroup が使用できる CPU 時間の量を設定するために使用されます。2 つのファイルは連携して CPU 使用量の上限を設定します。両方のファイルの単位はマイクロ秒 (us) です。cpu.cfs_period_us の値の範囲は 1 ミリ秒 (ms) から 1 秒 (s) です。cpu.cfs_quota_us の値は 1 ミリ秒より大きくなる場合があります。
CPU制限の使い方を説明するために例を挙げてみましょう。無限ループを書くと

ここに画像の説明を挿入

実行中は、topを使用して占有率が100%に達したことを確認します。

ここに画像の説明を挿入

cfs_quota_usを設定するには次のコマンドを実行します。

エコー 20000 > /sys/fs/cgroup/cpu/test/cpu.cfs_quota_us

このコマンドは、プロセスの CPU 使用率を 20% 削減し、プロセス PID を cgroup に追加することを意味します。

ここに画像の説明を挿入

もう一度 top を実行すると、CPU 使用率が低下していることがわかります。

ここに画像の説明を挿入

cgroup 内のメモリを制限する

コードにメモリ リークなどのバグがあると、システム メモリが枯渇し、メモリ割り当て不足により他のプログラムの動作が異常になります。システムがスワップ パーティションで構成されている場合、システムは大量のスワップ パーティションを使用するため、システムの動作が非常に遅くなります。
プロセス メモリに対する cgroup の主な制御は次のとおりです。

  • cgroup内のすべてのプロセスが使用するメモリの合計を制限する
  • cgroup内のすべてのプロセスで使用される物理コンテンツ+スワップの合計量を制限する
  • cgroup 内のすべてのプロセスで使用できるカーネル メモリとその他のカーネル リソースの合計量を制限します (CONFIG_MEMCG_KMEM)。

ここでのカーネル メモリの制限は、現在のプロセスによって占有されているカーネル スペース、ソケットによって占有されているメモリ スペースなど、cgroup によって現在使用されているカーネル リソースを制限することを意味します。メモリが不足している場合、現在の cgroup がプロセスの作成を継続したり、カーネルからさらにカーネル リソースを要求したりできなくなる可能性があります。

次の例は、cgroup がメモリを制御する方法を示しています。

#include <iostream>
#include <sys/types.h>
#include <cstdlib>
#include <cstdio>
#include <文字列.h>
#include <unistd.h>

#CHUNK_SIZE 512 を定義する


int メイン()
{
   整数サイズ = 0;
   char *p = nullptr; 
   ながら(1)
   {
          if((p = (char*)malloc(CHUNK_SIZE))==nullptr)
          {
              壊す;
         }

      memset(p, 0, CHUNK_SIZE);
       printf("[%u]-- [%d]MBが割り当てられています ", getpid(), ++size);
       睡眠(1);
   }
    
   0を返します。
}

まず、/sys/fs/cgroup/memoryの下にサブディレクトリを作成してサブcgroupを作成します。たとえば、ここではテストディレクトリを作成します。

$mkdir /sys/fs/cgroup/memory/test

テストディレクトリには以下のファイルが含まれています

ここに画像の説明を挿入

各ファイルの機能は以下に簡単に紹介されています。

書類例示する
cgroup.イベント制御eventfd のインターフェース
メモリ使用量(バイト単位)現在使用されているメモリを表示します
メモリ制限バイト数現在のメモリ制限を設定/表示します
メモリ.失敗数メモリ使用量が制限値に達した回数を表示します
メモリ最大使用量バイト数最大履歴メモリ使用量
メモリのソフト制限バイト数現在のメモリ制限を設定/表示します
メモリ統計現在のcgroupのメモリ使用量を表示します
メモリ使用階層現在の cgroup にサブ cgroup のメモリ使用量を含めるかどうかを設定/表示します。
メモリを強制的に空にする現在の cgroup で可能な限り多くの回収可能なメモリを直ちに回収するようにシステムをトリガーします。
メモリ圧力レベルcgroup.event_control と一緒に使用するメモリ不足の通知イベントを設定します。
メモリのスワップ現在の swappiness を設定して表示する
メモリ移動時の移行チャージプロセスが占有するメモリを別の cgroup に移動するときに、そのメモリも移動するかどうかを設定します。
メモリ.oom_control OOMコントロール関連の設定/表示
メモリ.numa_stat NUMA関連メモリを表示する

次に、memory.limit_in_bytes ファイルに書き込んで制限を設定します。ここでは、下の図に示すように、5Mの制限が設定されています。

ここに画像の説明を挿入

次の図に示すように、上記の例のプロセスをこのcgroupに追加します。

ここに画像の説明を挿入

スワップスペースの影響を受けないようにするには、次の図に示すように、swappiness を 0 に設定して、現在の cgroup がスワップを使用しないようにします。

ここに画像の説明を挿入

物理メモリが上限に達すると、システムのデフォルトの動作では、メモリを要求し続けている cgroup 内のプロセスが強制終了されます。では、この動作をどのように制御するのでしょうか?つまり、memory.oom_control を設定します。このファイルには、現在の cgroup に対して OOM-killer を開始するかどうかを制御するフラグが含まれています。このファイルに 0 が書き込まれると、OOM-killer が起動します。カーネルがプロセスに十分なメモリを割り当てられない場合、カーネルはプロセスを直接強制終了します。このファイルに 1 が書き込まれると、OOM-killer は起動しません。カーネルがプロセスに十分なメモリを割り当てられない場合、カーネルは空きメモリができるまでプロセスを一時停止し、その後実行を続けます。同時に、memory.oom_control には読み取り専用の under_oom フィールドも含まれており、これは現在の状態が OOM 状態に入ったかどうか、つまり一時停止されたプロセスがあるかどうかを示すために使用されます。プロセスが強制終了されたかどうかを示す読み取り専用の killed_oom フィールドもあります。

cgoupプロセスの数を制限する

cgroup には pids と呼ばれるサブシステムがあり、cgroup とそのすべての子孫 cgroup で作成できるタスクの合計数を制限します。ここでのタスクは、fork 関数と clone 関数によって作成されたプロセスを指します。clone 関数はスレッドも作成できるため、ここでのタスクにはスレッドも含まれます。
cgroup ツリーは以前にマウントされているため、ここで子 cgroup を直接作成し、test という名前を付けます。コマンドは以下のとおりです

ここに画像の説明を挿入

テストディレクトリ内のファイルを見てみましょう

ここに画像の説明を挿入

ここで、pids.current は、現在の cgroup とそのすべての孫 cgroup 内のプロセスの合計数を示します。

ここに画像の説明を挿入

pids.max 現在の cgroup とそのすべての孫 cgroup によって作成できるプロセスの最大数。

ここに画像の説明を挿入

実験してpids.maxを1に設定してみましょう

ここに画像の説明を挿入

次に、現在のbashプロセスをcgroupに追加します。

ここに画像の説明を挿入

ランダムにコマンドを実行します。現在のウィンドウでは pids.current が pids.max と等しいため、プロセスの作成は失敗します。

ここに画像の説明を挿入

現在の cgroup の pids.current と pids.max は、現在の cgroup とすべての子孫 cgroup のすべてのプロセスを表すため、子孫 cgroup の pids.max サイズは親 cgroup のサイズを超えることはできません。超過するとどうなりますか? pids.maxを3に設定する

ここに画像の説明を挿入

現在のプロセス数は2です

ここに画像の説明を挿入

シェルウィンドウを再度開き、孫cgroupを作成し、pids.maxを5に設定します。

ここに画像の説明を挿入

現在のシェルのbashプロセスをcroup.procsに書き込む

ここに画像の説明を挿入

元のシェルウィンドウに戻り、コマンドをランダムに実行して、実行が失敗したことを確認します。

ここに画像の説明を挿入

ご覧のとおり、子 cgroup 内のプロセス数は、自身の pids.max によって制限されるだけでなく、祖先 cgroup の pids.max によっても制限されます。

Docker における cgroup の具体的な使い方を徹底的に理解する方法についての記事はこれで終わりです。Docker cgroup に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Dockerの核となる原則であるCgroupの詳細な説明
  • Docker基盤技術の適用に関する詳細な説明 名前空間Cgroup
  • docker cgroupリソース監視の詳細な説明
  • cgroups を使用して Docker コンテナのリソース使用量を制限する方法の詳細な説明

<<:  CSS3 オーバーフロープロパティの説明

>>:  javascript:void(0) の意味と使用例

推薦する

Zabbixについて管理者ログインパスワードを忘れた場合、パスワードをリセットする

Zabbix 管理者ログイン パスワードのリセットに関する問題は次のとおりです。 1. 問題の説明:...

CSS 3.0 テキストホバージャンプ特殊効果コード

これは、CSS 3.0 で実装されたテキストのホバーとジャンプ効果です。効果は次のとおりです。 以下...

JavaScript の組み込みオブジェクト 数学と文字列の詳細な説明

目次数学オブジェクト共通プロパティ一般的な方法Math.random()文字列メソッド長さプロパティ...

jQueryはアコーディオンの小さなケースを実装します

この記事では、アコーディオンを実装するためのjQueryの具体的なコードを参考までに紹介します。具体...

WEB 標準ウェブページ構造

背景画像でも、ページ上のテキストサイズでも、1 ピクセルの違いは非常に明白です。そして、私は学生時代...

uniappを使用してWeChatミニプログラムでEChartsを使用する方法

今日は、uniapp を使用して Echarts を統合し、マップ チャートを表示します。 mpvu...

Jenkins初心者のためのDockerデプロイメントチュートリアルの詳細な説明

この記事では、docker 経由で Jenkins+Maven+SVN+Tomcat をデプロイし、...

ゲーム着物メモ問題の簡単な分析

本日、ゲームを再起動した後、バックアップしたデータをターゲットデータベースにインポートできないことが...

LinuxシステムにおけるMySQLの一般的な操作コマンド

仕える: # chkconfig --list すべてのシステムサービスを一覧表示する# chkco...

CentOS 7 で rpm パッケージを使用して MySQL 5.7.18 をインストールする

最近、MySQL を使っています。Linux での mysql-installation という記事...

誰もが知っておくべきウェブサイトのユーザビリティに関する 10 のヒント

これ以上時間を無駄にせず、早速本題に入りましょう。 1. ロゴに代替テキストを追加するこれには 2 ...

初心者でもjsのtypeofとinstanceofの違いを理解できます

目次1. 型2. インスタンス3. 違い1. 型typeof 演算子は、評価されていないオペランドの...

Alibaba Cloud で MySQL リモート接続を構成するための詳細な手順

序文ご存知のとおり、デフォルトでは、Alibaba Cloud にインストールされている MySQL...

CentOS 7 で MySQL 8 の複数のインスタンスを設定する詳細なチュートリアル (必要な数だけ設定できます)

原因最近、プロジェクトのリファクタリングを始めたのですが、マスタースレーブと読み取り書き込み分離を使...

React 高階コンポーネント HOC 使用方法の概要

HOCを紹介する一文高階コンポーネント (HOC) とは何ですか? 公式ドキュメントによると、「高階...