【Docker】イメージとコンテナの違い:設計図と実体

Docker

こんにちは、かつコーチです。
Docker Desktopのインストールが終わり、いよいよDockerの学習が本格的にスタートします。
最初の関門になりやすいのが、「イメージ」と「コンテナ」という2つの言葉の違いです。
似たような場面で登場するため混同しがちですが、この2つの関係を理解することがDocker学習の土台になります。
この記事では、実際にコマンドを打ちながら、両者の違いを体で覚えていきます。

イメージとコンテナとは

イメージ=設計図、コンテナ=実体

イメージとは、コンテナを作るための設計図・型紙です。
「Ubuntuに、Python 3系と必要なライブラリがインストールされた状態」といった、環境そのものがパッケージ化されたファイルの集合を指します。
コンテナとは、このイメージを元に実際に起動された、動作している実体のことです。
料理に例えるなら、イメージは「レシピと材料一式がセットになった状態」、コンテナは「そのレシピを元に実際に調理して出来上がった1皿」に近いイメージです。
同じレシピ(イメージ)からは、何度でも同じ料理(コンテナ)を作り直せます。

なぜこの2つを分けて考える必要があるのか

イメージとコンテナが分離されているからこそ、Dockerは柔軟に使えます。
1つのイメージから、テスト用・検証用・本番用と、複数のコンテナを同時に起動できます。
コンテナに問題が起きても、イメージ自体は変化しないため、いつでも同じ状態のコンテナを作り直せます。
この「作り直せば必ず同じ環境に戻る」という性質が、Dockerの再現性の高さの正体です。

コマンドで違いを体感する

docker imagesでイメージ一覧を見る

手元にどんなイメージがあるかは、docker imagesコマンドで確認できます。

docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d2c94e258dcb   2 weeks ago    13.3kB

REPOSITORYがイメージの名前、TAGがバージョンを表すラベルです。
前回の記事で実行したhello-worldイメージが、ここに設計図として残っていることが分かります。

docker psでコンテナ一覧を見る

一方、実際に動いている(または動いていた)コンテナは、docker psコマンドで確認します。

docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED        STATUS                     NAMES
a1b2c3d4e5f6   hello-world   "/hello"   2 minutes ago  Exited (0) 2 minutes ago   festive_curie

-aオプションを付けると、現在停止中のコンテナも含めて一覧表示されます。
IMAGE列を見ると、このコンテナがどのイメージから作られたのかが分かるようになっています。

1つのイメージから複数のコンテナを起動する

イメージとコンテナが1対多の関係にあることを、実際に確認してみましょう。

docker run --name container-a hello-world
docker run --name container-b hello-world
docker ps -a

--nameオプションで名前を変えながら2回docker runを実行すると、docker imagesに表示されるイメージはhello-world1つのままなのに、docker ps -aにはcontainer-acontainer-bという2つのコンテナが表示されます。
これが、1つの設計図から複数の実体を作れるというイメージとコンテナの関係です。

よくあるつまずきポイント

Before/After:イメージを消せばコンテナも消えると思い込む

初心者が混同しやすいのが、イメージとコンテナの依存関係の向きです。

❌Before:コンテナが動いたままイメージを削除しようとする

docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference
"hello-world" (must force) - container a1b2c3d4e5f6 is using its referenced image

私も学習を始めた頃、「イメージを消せば関連コンテナもまとめて消えるはず」と勘違いし、このエラーに遭遇しました。
実際は逆で、コンテナがイメージを参照している間は、イメージ側を削除できない仕組みになっています。

✅After:先にコンテナを削除してからイメージを削除する

docker rm container-a container-b
docker rmi hello-world

コンテナを先に削除し、そのイメージを参照するコンテナがなくなった状態にしてから、イメージを削除します。
「コンテナはイメージに依存している」という向きを覚えておくと、この手のエラーに悩まされずに済みます。
コンテナの削除方法は、次々回の「コンテナのライフサイクル管理(ps・stop・rm)」で詳しく扱います。

応用・一歩先の使い方

イメージは「レイヤー」が積み重なってできている

一歩踏み込むと、イメージは1枚の板ではなく、複数のレイヤー(層)が積み重なって構成されています。
ベースになるOSのレイヤーの上に、ライブラリを追加したレイヤー、アプリケーションコードを追加したレイヤーが順に重なっているイメージです。
このレイヤー構造のおかげで、共通する土台部分(例えばUbuntuのベースイメージ)は複数のイメージ間で使い回され、ディスク容量やダウンロード時間の節約につながっています。
レイヤーの仕組みは、Dockerfileの書き方を学ぶ回でさらに詳しく取り上げます。

まとめ

この記事のポイント

  • イメージは設計図、コンテナはその設計図から作られた実体
  • docker imagesでイメージ一覧、docker ps -aでコンテナ一覧を確認できる
  • 1つのイメージから複数のコンテナを起動できる
  • コンテナはイメージに依存しているため、削除する際はコンテナが先
  • イメージは複数のレイヤーが積み重なって構成されている

次に読むべき記事

コンテナの起動オプションをもっと詳しく知りたい方は「docker runでコンテナを起動する基本」に進んでください。
コンテナの停止・削除を体系的に学びたい方は「コンテナのライフサイクル管理(ps・stop・rm)」も合わせてどうぞ。

タグ: Docker, 初心者向け, 入門

タイトルとURLをコピーしました