Dockerを使うときは、まずベースイメージを作ります。それを起動して変更を加えると、その変更は別のイメージを形成するレイヤーに保存されます。
最終的には、PostgreSQLインスタンス用のイメージとWebアプリケーション用のイメージができあがり、その変更は継続して保存されます。
コンテナとは何ですか?
イメージのインスタンスをコンテナと呼びます。あなたが説明したように、レイヤーの集合体であるイメージがあります。このイメージを起動すると、そのイメージの実行中のコンテナができます。同じイメージのコンテナをたくさん持つことができます。
すべてのイメージは docker images
で見ることができ、実行中のコンテナは docker ps
で見ることができます (すべてのコンテナは docker ps -a
で見ることができます)。
つまり、あるイメージの実行中のインスタンスがコンテナということになります。
Automating Docker Deployments】1の記事より。
Dockerlandでは、imageとcontainersがあります。この2つは密接に関連していますが、異なるものです。私にとって、この二分法を理解することで、Dockerが非常に明確になりました。
イメージとは、不活性で不変のファイルであり、基本的にはコンテナのスナップショットを意味します。イメージはbuildコマンドで作成され、runコマンドで起動するとコンテナが生成されます。イメージは、registry.hub.docker.comなどのDockerレジストリに保存されます。イメージはかなりの大きさになるため、他のイメージを重ねて構成するように設計されており、ネットワークでイメージを転送する際のデータ量を最小限に抑えることができます。
ローカルのイメージは、docker images
を実行することで一覧できます。
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 13.10 5e019ab7bf6d 2 months ago 180 MB
ubuntu 14.04 99ec81b80c55 2 months ago 266 MB
ubuntu latest 99ec81b80c55 2 months ago 266 MB
ubuntu trusty 99ec81b80c55 2 months ago 266 MB
<none> <none> 4ab0d9120985 3 months ago 486.5 MB
注意すべき点は?
1.IMAGE IDは、画像の真の識別子の最初の12文字です。1つの画像に対して多くのタグを作成することができますが、それらのIDはすべて同じになります(上記のとおり)。
2.2. VIRTUAL SIZE は、下にあるすべての異なるレイヤーのサイズを足し合わせたものなので、_仮想的なものです。つまり、この列のすべての値の合計は、これらの画像すべてが使用するディスク容量よりもはるかに大きいと思われます。
3.REPOSITORY列の値は、docker build
コマンドのt
フラグ、または既存のイメージにdocker tag
を付けたものです。イメージに意味のある命名法を使ってタグ付けするのは自由ですが、dockerは docker push
や docker pull
の際にレジストリの場所としてタグを使用することを知っておいてください。
4.4. タグの完全な形は [REGISTRYHOST/][USERNAME/]NAME[:TAG]
です。上記の「ubuntu」の場合、REGISTRYHOSTは「registry.hub.docker.com」と推測されます。つまり、my-application
というイメージをdocker.example.com
のレジストリに保存する場合は、そのイメージにdocker.example.com/my-application
というタグを付ける必要があります。
5.5. TAGカラムは、_full_タグの[:TAG]部分に過ぎません。これは残念な用語です。
6.6. latest
タグは魔法のようなものではなく、タグを指定しなかったときのデフォルトのタグです。
7.7. タグの付いていない画像は、その IMAGE ID によってのみ識別することができます。これらの画像には、<none>
タグと REPOSITORY が付与されます。忘れるのは簡単ですよね。
イメージに関する詳しい情報は、Docker documentationおよびgrossaryを参照してください。
プログラミングに例えると、イメージがクラスならば、コンテナはクラスのインスタンス、つまりランタイムオブジェクトです。コンテナは、アプリケーションを実行するための環境を軽量かつポータブルにカプセル化したもので、Dockerを使用する理由にもなります。
ローカルで動作しているコンテナを見るには、docker ps
を使用します。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2ff1af05450 samalba/docker-registry:latest /bin/sh -c 'exec doc 4 months ago Up 12 weeks 0.0.0.0:5000->5000/tcp docker-registry
ここでは、docker レジストリを docker 化したものを実行して、イメージを保存するプライベートな場所を確保しています。ここでもいくつか注意点があります。
1.IMAGE IDと同様、CONTAINER IDもコンテナの真の識別子です。形は同じですが、異なる種類のオブジェクトを識別します。
2.2. docker ps
は running コンテナのみを出力します。docker ps -aで全てのコンテナ(_running_または_stopped_)を見ることができます。 3.NAMES は、
--name` フラグによって起動したコンテナを識別するために使用できます。
私がDockerを使い始めてすぐに感じた不満の1つは、タグ付けされていないイメージや停止したコンテナが絶え間なく蓄積されることでした。この蓄積により、ハードディスクが最大になってラップトップがスローダウンしたり、自動化されたビルドパイプラインが停止したりしたことが何度かありました。どこにでもあるコンテナ」と言っても過言ではありません。
docker rmiと最近の
dangling=true` クエリを組み合わせることで、タグ付けされていないイメージをすべて削除することができます。
docker images -q --filter "dangling=true" | xargs docker rmi
.
Dockerは既存のコンテナの背後にあるイメージを削除することができないので、まずdocker rm
で停止したコンテナを削除する必要があるかもしれません。
docker rm `docker ps --no-trunc -aq`
これらはDockerの既知のペインポイントであり、将来のリリースで対処されるかもしれません。しかし、イメージとコンテナについて明確に理解していれば、いくつかの実践でこれらの状況を回避することができます。
1.1. 無駄に停止したコンテナは、必ず docker rm [CONTAINER_ID]
で削除する。
2.2. 常に docker rm [IMAGE_ID]
を使って、無用で停止しているコンテナの背後にあるイメージを削除する。
コンテナを実行中のイメージと考えるのが最も簡単ですが、これは正確ではありません。
イメージは実際には、コンテナに変えることができるテンプレートです。イメージをコンテナにするために、Dockerエンジンはイメージを受け取り、その上に読み書き可能なファイルシステムを追加し、ネットワークポート、コンテナ名、ID、リソース制限などの様々な設定を初期化します。実行中のコンテナには、現在実行中のプロセスがありますが、コンテナは停止することもできます(Dockerの用語ではexited)。終了したコンテナは、再起動することができ、設定やファイルシステムの変更を維持することができるので、イメージとは not です。