Docker のシステムの全体像を理解するためにまとめてみた.
イメージ,コンテナ
まず,Docker を利用する上で中心となる「イメージ」,「コンテナ」の意味を確認する.
- イメージ image
- 意味
ファイルシステムのこと.依存関係のあるソフトウェアを含め,1 つのアプリケーションの実行に必要な全てのファイルを含んでいる(以下参照). - イメージ(「ふわっとした理解をする」方の「イメージ」です)
ファイルシステム全体の状態を保存したスナップショットのようなものであり,OS(ファイルシステム),アプリケーション,内部のデータまで全ての状態が記録されているのがイメージである. - 実体
複数のレイヤー(ファイルの実体やメタ情報を含んだバイナリファイル.親子関係がある.)の集合体.Read Only で書き込みはできない.Dockerfile
はレイヤーを順に構成するための命令が書かれた手順書である. - イメージに含まれるファイル
- 意味
- コンテナ container
以下,ドキュメントのイメージ,コンテナの説明部分.
Fundamentally, a container is nothing but a running process, with some added encapsulation features applied to it in order to keep it isolated from the host and from other containers. One of the most important aspects of container isolation is that each container interacts with its own, private filesystem; this filesystem is provided by a Docker image. An image includes everything needed to run an application -- the code or binary, runtimes, dependencies, and any other filesystem objects required.
Docker の全体像を理解する
Docker 自体はクライアント / サーバ の構成となっている.Docker Client から命令を送信し,Docker daemon がそれを処理する.
CLI はユーザと Docker daemon とのインタフェースに過ぎない.処理の主体は Docker daemon であり,以下の処理は全て Docker daemon が担う.
Docker の構成については以下の画像が参考になる.CLI からの命令が全て Docker daemon に送られているのが分かる.
https://geekflare.com/docker-architecture/ より引用
- Docker daemon が担う主要な処理
- docker build:Dockerfile に基づきイメージをビルド
- docker pull:イメージをレジストリ(Docker Hub など)からホスト(ローカル)にダウンロード
- docker run:イメージに基づきコンテナの生成・実行
イメージのビルドの流れ:CLI と Docker daemon
Docker の全体像を理解したところで,イメージのビルドについてまとめる.Docker イメージのビルドの流れは以下のようになっている(補足として処理の主体を括弧で示した).
- (CLI)CLI で
docker build [PATH | URL]
コマンドを実行 - (CLI)指定した
PATH
orURL
のディレクトリ,サブディレクトリを再帰的に処理し,ビルドコンテキストを作成 - (CLI to Docker daemon)ビルドコンテキストを Docker daemon に送信
- (Docker daemon)Dockerfile のパース,バリデーション(syntax error など)
- (Docker daemon)Dockerfile 内の命令を順に実行し,イメージをビルド
ビルドコンテキスト
ビルドコンテキストを理解する.
- ビルドコンテキスト build context
PATH
(orURL
)で指定されたディレクトリのファイル全体のこと.指定したディレクトリ(or リポジトリ)のその時点での状態を表すため,「コンテキスト context」という言葉が使われる.docker build
実行時に CLI から Docker daemon に送信されるが,実際には tar で圧縮されて Docker daemon へ送信される.
ビルドコンテキストと .dockerignore
ファイル
Docker daemon に送るビルドコンテキストを作成する際に重要なのが .dockerignore
である.
.dockerignore
ビルドコンテキストに送信しないファイル名,ディレクトリ名のパターンを記述するためのテキストファイル..gitignore
の Docker 版というイメージが一番わかりやすい.ビルドコンテキストのルートディレクトリに置くとdocker build
実行時に CLI により参照される.
docker build [PATH | URL]
を実行した際,デフォルトでは指定したルートディレクトリ配下の全てのファイルがビルドコンテキストに含まれる.これは,プロジェクトが大きくなったり,容量の大きなファイルが存在する場合にビルドコンテキストの作成時間が大きくなることを意味する.
そうなったときに,ビルドコンテキストの容量を出来る限り小さくするための設定を書いておくのが .dockerignore
である.指定したルートディレクトリに .dockerignore
を置くと,ビルドコンテキストを送信する前に CLI がこのファイルに書かれたファイル名,ディレクトリ名のパターンを参照し,そのパターンに合致したファイルをビルドコンテキストに含めないようにしてくれる.
例えば,node_modules
(npm package),.venv
(Python virtual environment) などの容量の大きいディレクトリを .dockerignore
に記述することでビルドコンテキストから除外できる.
記述方法については以下を参照.
ビルドコンテキストが送信されるまでの流れを以下に整理してみた..dockerignore
に関連する処理は全て CLI が担う(括弧内は処理の主体).
- (CLI)
docker build [PATH | URL]
の実行 - (CLI)指定されたルートディレクトリの
.dockerignore
を参照し,ビルドコンテキストに含めないファイル,ディレクトリ名のパターンを正規表現として生成 - (CLI)ビルドコンテキストに含めないファイルの検索,列挙
- (CLI to Docker daemon)Docker daemon へビルドコンテキストを送信
- (Docker daemon)Dockerfile のパース,バリデーション,実行
注意:ビルドコンテキストと ADD
,COPY
Dockerfile のパースはクライアントサイド(docker build
を実行した場所)ではなく,サーバーサイド(Docker daemon)で実行される.つまり,Dockerfile のパース,実行は全てのファイルがビルドコンテキストとして送信された後である.
よくある勘違いとして,「Dockerfile 内の ADD
,COPY
で指定されたファイルだけがビルドコンテキストとして送信される」というものがあるが(私だけかもしれないが),上記の理由によりこれは間違いである.ADD
,COPY
が実行されるのはビルドコンテキスト作成後であるから,もし送信したくないファイルがある場合は .dockerignore
に記述して除外する必要がある.
ビルドコンテキストの作成と .dockerignore
に関する処理の流れを以下にまとめた(括弧内は処理の主体).
- (CLI)
.dockerignore
の読み込み,ビルドコンテキストの構築 - (CLI to Docker daemon)Docker daemon へビルドコンテキストを送信
- (Docker daemon)Dockerfile のパース,実行(
ADD
,COPY
でビルドコンテキストからイメージへファイルを追加)
Remember that the daemon could be running on a remote machine and that no parsing of the Dockerfile happens at the client side (where you’re running
docker build
). That means that all the files at PATH get sent, not just the ones listed toADD
in the Dockerfile.The transfer of context from the local machine to the Docker daemon is what the docker client means when you see the “Sending build context” message.
補足:用語
- プロセス process メモリ上で実行状態にあるプログラム
参考
イメージの実体やファイルシステムを理解するための記事
書籍
- みんなの Docker Kubernetes:1 - 3 章