🐳
【Docker入門】Docker イメージレイヤーの構成原理
🐳 Docker イメージレイヤーの構成原理
🧭 概要
Dockerは効率的なビルドとキャッシュ活用のために、ファイルシステムの変更単位でイメージレイヤーを作成します。
ただし、すべてのDockerfile命令がレイヤーを生成するわけではなく、ファイルシステムに実際の変化があった場合のみです。
🧱 Dockerレイヤーとは?
- Dockerは「イメージ=複数のレイヤーの集合体」として管理。
- レイヤー単位でキャッシュを共有し、イメージの冗長を防ぎ、効率化を図る。
- コンテナ実行時にも、レイヤーを積み重ね、最上部に書き込み可能なコンテナレイヤーをマウント。
🔗 UnionFS の役割
Dockerは「Union File System(UnionFS)」を使って、複数レイヤーを1つのファイルシステムのように見せます。
例:mount -t ufs -o upperdir=dir1,lowerdir=dir2,workdir=wrk -f myufs dirM
-
upperdir
(上位ディレクトリ)が優先され、同一ファイルがある場合はそちらを採用。 - OverlayFS, VFS, devicemapper などがサポートされ、主に OverlayFS が使われる。
📄 どの命令がレイヤーを作るのか?
命令 | レイヤー生成 | 備考 |
---|---|---|
FROM |
✅(ベース) | 既存イメージから開始。新規ではないがレイヤー構成に加わる。 |
LABEL |
❌ | メタデータ変更のみ。 |
COPY |
✅ | ファイル追加は新しいレイヤーとして扱われる。 |
RUN |
✅ | ファイルシステム変更があればレイヤー生成。 |
CMD |
❌ | 実行コマンドのメタデータのみ。 |
📎 ポイント:同じ RUN mkdir
を何度も書いても、変化がなければ同じレイヤーIDになる場合もあるが、COPY
は重複でも毎回新しいレイヤーが生成される傾向。
🧪 テスト結果まとめ
✔ 同一コマンドの繰り返し
RUN mkdir -p /test
COPY ./test.txt .
COPY ./test.txt .
RUN mkdir -p /test
-
mkdir
は最初の1回以外、レイヤーが再利用されるケースあり。 -
COPY
は毎回レイヤーが生成される(データが変わらなくても)。
✔ キャッシュ利用の挙動確認
- 既存レイヤーが存在すれば
"Using cache"
と出力され、再ビルド不要。 - レイヤーの差分は
/var/lib/docker/overlay2
にdiff/
として保存。
🧠 Dockerfile 最適化のポイント
❌ 非効率な例
RUN make /app
RUN rm -r $HOME/.cache
-
make
のキャッシュは次のレイヤーに残り、イメージサイズ削減にならない。
✅ 効率的な例
RUN make /app && rm -r $HOME/.cache
- 1レイヤー内でビルドとキャッシュ削除を完結させ、不要ファイルが残らない。
📌 補足:Docker 23以降の変化
- Docker 23 バージョンから、デフォルトビルダーが BuildKit に変更。
-
buildx
を使用するようになり、レイヤー構成やキャッシュ処理に違いが生じる可能性あり。
📝 まとめ
- Dockerはファイルシステムの差分ごとにレイヤーを構成し、キャッシュ効率・イメージサイズを最適化。
- Dockerfileを記述する際は、レイヤー数を減らす工夫(複数命令の結合や不要ファイル削除)を行うことで、効率的な運用が可能。
- バージョン差異やBuildKitの導入による仕様変更にも注意が必要。
Discussion