DUICUO

Dockerカーネル技術の原則:名前空間

[[410507]]

Dockerはリソースの分離に名前空間を使用します。これはカーネルが提供する分離メカニズムです。名前空間内では、各プロセスは一貫したリソースビューを参照します。逆に、異なる名前空間内のプロセスは異なるリソースビューを参照します。例えば、2つのプロセスが同じネットワーク名前空間内にある場合、それらは同じネットワーク情報(ネットワークインターフェースカード、IPアドレス、ルーティングなど)を参照し、localhost経由で相互にアクセスできます。一般的に使用される名前空間は6つあります。Linuxカーネル4.6以降ではCgroup名前空間が追加され、5.6以降ではclock名前空間が追加されました。

名前空間

システムコールパラメータ

隔離コンテンツ

UTS

クローン_NEWUTS

ホスト名とドメイン名

IPC

クローン_NEWIPC

セマフォ、メッセージキュー、共有メモリ

PID

クローン_NEWPID

プロセス番号

ネットワーク

クローン_ニューネット

ネットワーク デバイス、ネットワーク スタック、ポートなど。

マウント

クローン_NEWNS

マウントポイント(ファイルシステム)

ユーザー

CLONE_NEWUSER

ユーザーとユーザーグループ

Cグループ

クローン_新しいグループ

cgroup ルートディレクトリ

時間

クローン_NEWTIME

クロック

ここで少し詳細を述べます。上記の表にあるマウント名前空間を作成するためのシステムコールパラメータは、CLONE_NEWMOUNTではなくCLONE_NEWNSです。文字通りの意味は、名前空間を作成することです。これは歴史的な理由によるものです。マウント名前空間が最初の名前空間であったため、カーネル開発者は後に他の名前空間が追加されることを予想していなかったため、CLONE_NEWNSをマウント名前空間用に予約したと考えられます。

名前空間の分離だけでは不十分であることは明らかです。前述の分離機能を除けば、他のすべては同じです。例えば、カーネルバージョン5.6より前では、すべてのコンテナとオペレーティングシステムは同じ時計を共有していました。オペレーティングシステムの時刻が変更されると、すべてのコンテナの時刻も変更されていました。


名前空間の実装原理も非常にシンプルです。各プロセス(task_struct)には、名前空間に関連する属性 nsproxy があり、これはプロセスが属する名前空間を表します。

構造体 task_struct {...

/* 名前空間 */

構造体 nsproxy *nsproxy;

...

}

nsproxyは、様々な名前空間を指すプロキシです。以下のように記述します。

新しいプロセスが生成されると、親プロセスの名前空間を継承します。そのため、コンテナ内のすべてのプロセスは同じ名前空間を共有します。Linuxクラスタでは、各プロセスの名前空間は「/proc/processID/ns/」以下のファイルを読み取ることで取得できます。