メインコンテンツまでスキップ

Docker の仕組み

· 約7分

Docker の内部アーキテクチャ、コンテナ実装の仕組み、低レベルストレージの仕組みについてのノートです。

内部アーキテクチャのコンポーネント

コンポーネント説明
Docker DaemonDocker の中核コンポーネント。デーモンプロセスとして動作し、コンテナの作成・起動・停止・削除などの操作を管理します。
Docker ClientDocker Daemon とやり取りするコマンドラインツール。ユーザーはこのツールでコマンドを送信し、Docker コンテナを操作します。
Docker RegistryDocker イメージを保管する中央リポジトリ。Docker Client を通じて必要なイメージをここから取得できます。
Docker Imageコンテナの土台となる読み取り専用のファイルシステムで、アプリケーション、依存ライブラリ、設定ファイルなどを含みます。Dockerfile から作成できます。
Docker ContainerDocker イメージのインスタンス。完全なファイルシステム、ランタイム環境、システムツールを含みます。

Docker Daemon と Docker Client の間の通信には RESTful API が使われます。Docker Client がコマンドを Docker Daemon に送信し、Docker Daemon がそれを受け取って処理し、最終的に結果を Docker Client に返します。

Docker Daemon がコンテナ作成のコマンドを受け取ると、まずローカルに必要な Docker イメージが存在するかを確認します。ローカルにイメージがなければ、Docker Daemon は Docker Registry から必要なイメージを取得します。ローカルにすでにイメージがあれば、そのイメージからコンテナを作成し、独立した名前空間の中で実行します。

コンテナの実行中、Docker Daemon はコンテナの出力とエラー情報を stdout と stderr に出力し、ユーザーは Docker Client でコンテナの出力を確認できます。コンテナが不要になったら、Docker Client からコマンドを送って停止できます。Docker Daemon はコンテナ内のプロセスに SIGTERM シグナルを送り、グレースフルに終了させます。一定時間内にプロセスが終了しない場合は SIGKILL シグナルを送り、プロセスを強制終了します。

コンテナ実装の仕組み

Docker コンテナの実装の仕組みは、以下のいくつかの側面に分けられます。

  1. 名前空間(Namespace):Docker は名前空間を使って、コンテナごとのプロセス、ネットワーク、ファイルシステム、ユーザーなどのリソースを分離します。各コンテナは自分専用の名前空間を持ち、コンテナ同士は互いに独立し、影響を与え合いません。
  2. コントロールグループ(Control Groups、略して Cgroups):Docker は Cgroups を使って、コンテナが使用する CPU、メモリ、ネットワーク帯域などのリソースを制限します。各コンテナには一定のリソース割り当てが与えられ、コンテナ同士がホストのリソースを公平に共有できます。
  3. ユニオンファイルシステム(Union File System):Docker はユニオンファイルシステムを使ってコンテナのファイルシステム分離を実現します。各コンテナは自分のファイルシステムを持ちながら、ホストのファイルシステムの一部を共有できます。この方式によりコンテナのファイルシステムは非常に軽量になり、素早く作成・破棄できます。
  4. コンテナイメージ(Container Image):Docker コンテナはコンテナイメージから作成されます。コンテナイメージは読み取り専用のファイルシステムで、アプリケーション、依存ライブラリ、設定ファイルなどを含みます。Docker はユニオンファイルシステムでイメージのレイヤー保存を実現しており、イメージの共有と再利用が可能になり、ストレージ容量とダウンロード時間を大幅に削減できます。
  5. コンテナランタイム(Container Runtime):Docker はコンテナランタイムを使ってコンテナを起動・管理します。コンテナランタイムはコンテナの名前空間、Cgroups、ユニオンファイルシステムを作成し、その後コンテナ内のプロセスを起動します。さらに、コンテナの状態やリソース使用状況を監視し、必要に応じてリソース割り当てを調整する役割も担います。

Docker の動作原理とは、つまり Docker Daemon と Docker Client のやり取りを通じて、Docker コンテナを作成・起動・停止・削除することです。Docker イメージは Docker コンテナの土台であり、Dockerfile から作成できます。Docker コンテナは独立した名前空間の中で動作し、分離性と安全性を提供します。

低レベルストレージの仕組み

Docker の低レベルストレージの仕組みは、主にコンテナイメージとデータボリュームの二つの側面に関わります。

コンテナイメージの保存

Docker はユニオンファイルシステム(Union File System)を使って、コンテナイメージのレイヤー保存を実現しています。コンテナイメージは複数の読み取り専用レイヤーで構成され、各レイヤーは共有・再利用できます。コンテナ起動時、Docker はこれらの読み取り専用レイヤーを結合し、その上に書き込み可能なレイヤーを重ねてコンテナのファイルシステムを構成します。この方式によりコンテナイメージは非常に軽量になり、素早く作成・破棄できます。

Docker はデフォルトで AUFS(Advanced Multi-Layered Unification File System)をユニオンファイルシステムとして使用しており、多層の結合、素早い作成と破棄、読み取り専用レイヤーの共有などの特性をサポートします。また、OverlayFS、DeviceMapper、Btrfs など他のユニオンファイルシステムもサポートしています。

データボリュームの保存

Docker コンテナのデータボリュームは、コンテナが読み書きできるディレクトリまたはファイルで、コンテナ間のデータ共有や永続化ストレージなどに使えます。Docker はホストマウントボリューム、名前付きボリューム、匿名ボリュームなど、複数の種類のデータボリュームをサポートしています。

ホストマウントボリュームは、ホスト上のディレクトリやファイルをコンテナにマウントするもので、コンテナはそのディレクトリやファイルを読み書きできます。名前付きボリュームは Docker が管理するデータボリュームで、名前を付けられるため管理と共有がしやすくなります。匿名ボリュームは Docker が自動生成するデータボリュームで、コンテナ内の一時データの保存に使われます。

Docker コンテナのデータボリューム保存は、主に Linux のファイルシステムマウント機構によって実現されています。コンテナ起動時、Docker はデータボリュームをコンテナ内の指定ディレクトリにマウントし、コンテナがそのディレクトリに書き込んだデータはボリュームに保存されます。コンテナ停止時、Docker はデータボリュームをアンマウントしますが、データはボリュームに残るため、永続化ストレージが実現されます。

まとめ

Docker のアーキテクチャは複雑ではありません。Client が RESTful API で Daemon に指示を送り、Daemon がイメージの取得とコンテナのライフサイクル全体の管理を担います。コンテナ自体は Linux の Namespace によるリソース分離と Cgroups によるリソース制限に依存し、ユニオンファイルシステムがイメージのレイヤー保存とコンテナの書き込み可能レイヤーを支えています。データの永続化はデータボリュームに任せ、ファイルシステムのマウント機構によってデータをコンテナのライフサイクルから独立させています。これらの仕組みを理解すれば、コンテナの「軽量・ポータブル・再利用可能」という特性も自然に説明がつくでしょう。

COMMENTS