コンテナイメージの仕組み ― レイヤー構造からセキュリティまで


コンテナイメージのレイヤー構造 Dockerfile FROM alpine:3.19 RUN apk add nodejs COPY ./app /app COPY config.yml /etc/ CMD ["node", "app.js"] build イメージ(読み取り専用) Layer 4: 設定ファイル Layer 3: アプリコード Layer 2: Node.js ランタイム Layer 1: Alpine Linux(ベースOS) 各レイヤーは不変 ― 変更時は Copy-on-Write で新しい層に記録
コンテナイメージのレイヤー構造のイメージ
ひよこ ひよこ

コンテナイメージってよく聞くけど、普通の「イメージ」とは違うの?

ペンギン先生 ペンギン先生

コンテナイメージは、アプリを動かすために必要なファイルや設定をまるごとパッケージにした「読み取り専用のテンプレート」だよ。料理でいうと「レシピ+材料セット」みたいなもので、これがあればどこでも同じ環境を再現できるんだ。

ひよこ ひよこ

どうやって作るの?

ペンギン先生 ペンギン先生

Dockerfileっていう設計図を書いて、docker build コマンドで組み立てるよ。たとえば「ベースOSはAlpine Linux」「Node.jsインストール」「アプリのコードをコピー」みたいな手順を1行ずつ書いていくんだ。

ひよこ ひよこ

レイヤーっていう仕組みがあるって聞いたけど、何なの?

ペンギン先生 ペンギン先生

Dockerfileの各命令が1つの「レイヤー(層)」になるんだ。ミルフィーユみたいに薄い層が重なっていて、Union FileSystemという技術で1つのファイルシステムに見せてるよ。変更があったレイヤーだけ差し替えればいいから、ビルドもダウンロードも高速なんだ。

ひよこ ひよこ

コンテナが動いてるときにファイルを変更したらどうなるの?

ペンギン先生 ペンギン先生

Copy-on-Write(CoW)っていう仕組みで、元のレイヤーはそのままに、変更分だけ新しい書き込み層に記録されるよ。だから元のイメージは汚れないし、同じイメージから何個コンテナを起動してもディスクの無駄がないんだ。

ひよこ ひよこ

イメージってどこに保存するの?

ペンギン先生 ペンギン先生

レジストリっていう倉庫に保存するよ。Docker Hubが一番有名で、AWSのECRやGoogleのGCRもあるね。タグ(例: myapp:v1.2)で管理するんだけど、タグは上書きできちゃうから、確実に特定したいときはsha256のダイジェスト値を使うのが安全だよ。

ひよこ ひよこ

イメージが大きすぎると困ることってあるの?

ペンギン先生 ペンギン先生

デプロイが遅くなるし、ストレージも食うから小さい方がいいね。マルチステージビルドっていうテクニックがあって、ビルド用の大きな環境でコンパイルして、実行用には最小限のファイルだけコピーするんだ。ベースイメージもAlpine(約5MB)やdistroless、scratchを選ぶとグッと小さくなるよ。

ひよこ ひよこ

セキュリティ面で気をつけることってあるの?

ペンギン先生 ペンギン先生

イメージの中に古いライブラリや既知の脆弱性が含まれていることがあるんだ。TrivyやSnykみたいなスキャンツールでCI/CDパイプラインに組み込んで、脆弱性を自動検出するのが今の標準的なやり方だよ。

ひよこ ひよこ

もっと進んだセキュリティ対策ってあるの?

ペンギン先生 ペンギン先生

サプライチェーンセキュリティっていう考え方が重要になってきてるよ。cosignやNotaryでイメージに電子署名を付けて「このイメージは改ざんされていない」と証明するんだ。さらにSBOMソフトウェア部品表)を添付して、どんなライブラリが入っているか透明にする動きも広がってるね。

ひよこ ひよこ

同じDockerfileでビルドしても毎回同じイメージになるの?

ペンギン先生 ペンギン先生

実はならないことが多いんだ。apt-get updateで取得されるバージョンが変わったり、タイムスタンプが違ったりするからね。「再現可能ビルド(Reproducible Build)」は意外と難しくて、ベースイメージのダイジェスト固定やパッケージバージョンのピン留めが必要になるよ。本番環境信頼性に直結する、奥が深いテーマだね。