Docker はリソースを分離します: 1. ファイル システム、2. ネットワーク、3. プロセス間の通信、4. 権限のためのユーザーとユーザー グループ、5. プロセス PID 内の PID とホスト、6. ホスト名とドメイン名前など
このチュートリアルの動作環境: linux5.9.8 システム、docker-1.13.1 バージョン、Dell G3 コンピューター。
Docker コンテナの本質
Docker コンテナの本質はホスト上のプロセスです。
Docker は、namespace によるリソースの分離、cgroups によるリソースの制限、および *コピーオンライト メカニズム* ファイル操作による高効率を実現します。
Linux 名前空間メカニズム
名前空間メカニズムは、リソース分離ソリューションを提供します。
PID、IPC、ネットワーク、およびその他のシステム リソースはグローバルではなくなりましたが、特定の名前空間に属します。
各名前空間の下のリソースは、他の名前空間の下のリソースに関連付けられます。透明、非表示。
Linux カーネル実装名前空間の主な目的の 1 つは、軽量の仮想化 (コンテナ) サービスを実装することです。同じ名前空間内のプロセスは、互いの変更を認識でき、外部プロセスについては何も知りません。独立性と分離を実現するためです。
名前空間で分離できるもの
コンテナが他のコンテナに干渉したくない場合は、次のことができる必要があります:
上記の分離により、コンテナはホストや他のコンテナから分離できます。
Linux 名前空間ではこれが可能です。
#namespace
分離されたコンテンツ |
システムコールパラメータ |
|
UTS
ホスト名とドメイン名 |
CLONE_NEWUTS |
|
IPC
セマフォ、メッセージキュー、共有メモリ |
CLONE_NEWIPC |
|
ネットワーク
ネットワーク デバイス、ネットワーク スタック、ポートなど |
CLONE_NEWNET |
|
PID
プロセス番号 |
CLONE_NEWPID |
|
マウント
マウント ポイント (ファイル システム) |
CLONE_NEWNS |
|
ユーザー
ユーザーとユーザー グループ |
CLONE_NEWUSER |
|
UTS 名前空間
UTS (UNIX 時間共有システム) 名前空間はホスト名とドメイン名の分離を提供するため、各 Docker コンテナーはホスト上で独立したホスト名とドメイン名を持つことができます。ネットワークは、ホスト マシン上のプロセスではなく、独立したノードとして見ることができます。
Docker では、各イメージには基本的に、提供するサービス名にちなんでホスト名という名前が付けられ、ホストには影響を与えません。
IPC 名前空間
プロセス間通信 (IPC) 用に設計された IPC リソースには、共通セマフォ、メッセージ キュー、共有メモリが含まれます。
IPC リソースを申請するときは、グローバルに一意の 32 ビット ID を申請します。
IPC 名前空間には、システム IPC 識別子と、POSIX メッセージ キューを実装するファイル システムが含まれます。
同じ IPC 名前空間内のプロセスは相互に参照できますが、異なる名前空間内のプロセスは相互に参照できません。
PID 名前空間
PID 名前空間の分離は非常に実用的です。プロセス PID の番号を付け直します。つまり、異なる名前空間にある 2 つのプロセスが同じ PID を持つことができます。 PID 名前空間には独自のカウント手順があります。
カーネルはすべての PID 名前空間のツリー構造を維持します。最上位の名前空間はシステムの初期化時に作成され、ルート名前空間と呼ばれます。新しく作成された PID 名前空間は子名前空間と呼ばれ、元の PID 名前空間は新しく作成された PID 名前空間の子名前空間、元の PID 名前空間は新しく作成された PID 名前空間の親名前空間となります。
このように、異なる PID 名前空間は階層システムを形成し、それらが属する親ノードは子ノードのプロセスを参照し、シグナルやその他の方法を通じて子ノードのプロセスに影響を与えることができます。ただし、子ノードは親ノードの PID 名前空間では何も見ることができません。
mount 名前空間
mount 名前空間は、ファイル システムのマウント ポイントを分離することによるファイル システムの分離のサポートを提供します。
分離後は、異なるマウント名前空間でのファイル構造の変更は相互に影響しません。
ネットワーク名前空間
ネットワーク名前空間は、主にネットワーク機器、IPv4、IPv6 プロトコル スタック、IP ルーティング テーブル、ファイアウォール、/proc/ net ディレクトリなどのネットワーク リソースの分離を提供します。 、/sys/class/net ディレクトリ、ソケットなど。
#ユーザー名前空間
ユーザー名前空間は、インストール関連の識別子と属性を分離します
名前空間の操作
名前空間 API には、clone() setns() unshare() と /proc 下のいくつかのファイルが含まれています どの名前空間が分離されているかを決定するには、次の 6 つのパラメータを 1 つ以上指定する必要があります。 | 6 つのパラメータは、上の表に記載されている CLONE_NEWUTS、CLONE_NEWIPC、CLONE_NEWPID、CLONE_NEWNET、CLONE_NEWUSER です。
clone()
clone() を使用して独立した名前空間を作成します。プロセスは次のとおりです。最も一般的なアプローチであり、Docker が名前空間を使用する最も基本的な方法です。 int clone(int(*child_func)(void *),void *child_stack,int flags, void *arg);
ログイン後にコピー
clone() は、Linux システム コール fork() のより一般的な実装であり、フラグを使用して使用する関数の数を制御できます。 CLONE_* フラグには 20 種類以上あり、クローン プロセスのあらゆる側面を制御します。
child_func は、子プロセスによって実行されるプログラムの main 関数に渡されます。 child_stack は、子プロセスによって使用されるスタック領域に渡されます。 flags は、次のことを示します。どの CLONE_* フラグ ビットが使用されているか、名前空間に関連する主なものは上記の 6 つです。 args はユーザー パラメーターを渡すために使用されます
/proc/[pid]/ns
ユーザーは /proc/[ を入力できますpid ]/ns ファイルを確認すると、別の名前空間を指しているファイルが表示されます。 ls -l /proc/10/ns
ログイン後にコピー
角括弧内の名前空間番号
2 つのプロセスが指す名前空間番号が同じ場合、それらは同じ内にあります。 namespaceリンクを設定する目的は、名前空間下のすべてのプロセスが終了しても、この名前空間は常に存在し、後続のプロセスが参加できるようにすることです。 --bind メソッドを使用して /proc/[pid]/ns ディレクトリ ファイルをマウントすると、リンク
touch ~/utsmount --bind /proc/10/ns/uts ~/uts
ログイン後にコピー
setns()
の機能も実現できます。 Docker docker exec コマンドを使用して、すでに実行中のコマンド上で新しいコマンドを実行する場合は、setns() を使用する必要があります。 setns() システムコールを通じて、プロセスは元の名前空間から既存の名前空間に結合します。
通常、プロセスの呼び出し元に影響を与えず、新しく追加された pid 名前空間を有効にするために、プロセスは次のようになります。 setns() に追加 関数の実行後、 clone() を使用して子プロセスを作成し、コマンドの実行を継続し、元のプロセスの実行を終了させます。
int setns(int fd, in nstype);
#fd 表示要加入namespace的文件描述符。是一个指向/proc/[pid]/ns目录的文件描述符,打开目录链接可以获得
#nstype 调用者可以检查fd指向的namespace类型是否符合实际要求,该参数为0则不检查
ログイン後にコピー
新しく追加された名前空間を利用するには、ユーザー コマンドを実行できる execve() 一連の関数を導入する必要があります。最も一般的に使用される関数は、/bin/bash とaccept パラメータ
unshare()
unshare() による元のプロセスの名前空間分離 Unshare は clone と非常によく似ています。新しいプロセスであり、元のプロセスで使用できます。
docker は
fork() システム コールを使用しません
fork は名前空間 API に属しません
強力なカーネル ツール cgroups
cgroups は Linux カーネルが提供するメカニズムで、一連のシステム タスクとそのサブタスクを必要に応じてリソース レベルに基づいて異なるレベルに統合 (または分離) できます。これにより、システム リソース管理の統一フレームワークが提供されます。
cgroups は、Linux のもう 1 つの強力なカーネル ツールです。cgroups を使用すると、名前空間によって分離されたリソースを制限できるだけでなく、リソースの重みを設定し、使用量を計算し、タスク (プロセスまたは郡) の開始を制御することもできます。 . 立ち止まって待ちます。率直に言うと、cgroup はタスク グループによって使用される物理リソース (CPU、メモリ、IO など) を制限および記録でき、Docker などの一連の仮想化管理ツールを構築する基礎となります。
cgroups の役割
cgroups は、個々のリソース制御からオペレーティング システム レベルまで、さまざまなユーザー レベルでのリソース管理のための統合インターフェイスを提供します。仮想化に関して、cgroups は 4 つの主要な機能を提供します。
- リソース制限
- cgroups は、タスクで使用される合計リソースを制限できます。
- アプリケーションの実行時に使用されるメモリの上限を設定すると、クォータを超えると OOM プロンプトが発行されます
- 優先順位の割り当て
- 割り当てられた CPU タイム スライスの数とディスク IO 帯域幅を通じて、実際には、実行中のタスクの優先順位を制御するのと同等です。
##リソース統計-
cgroups は、システムのリソース使用量をカウントできます。CPU 使用時間、メモリ使用量など。この機能は、請求に非常に適しています。-
#タスク制御
- cgroups はタスクを一時停止および再開できます
推奨学習: 「
docker ビデオ チュートリアル 」
以上がDocker が分離するリソースの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。