Docker イメージの働き
Working with Docker Images - Docker Documentation
http://docs.docker.com/userguide/dockerimages/
introduction では、Docker イメージの基本コンテナについて学びました。前のセクションでは、既に使っている Docker イメージを使いました。例として使ったのは、ubuntu
イメージと training/webapp
イメージです。
これまでは Docker のイメージを Docker ホストにダウンロードする方法をみてきました。もし対象となるイメージがホストに存在していなければ、レジストリからダウンロードします。デフォルトのレジストリは、Docker Hub の公開レポジトリです。
このセクションでは、Docker イメージのより詳細について学びます。
- 自分の Docker ホスト上でローカルなイメージの管理と起動
- 基本イメージの作成
- イメージを Docker Hub にアップロードする
ホスト上のイメージの一覧
ローカルのホスト上で持っているイメージの一覧を作成しましょう。そのためには docker images
コマンドを次のように実行します。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
training/webapp latest fc77f57ad303 3 weeks ago 280.5 MB
ubuntu 13.10 5e019ab7bf6d 4 weeks ago 180 MB
ubuntu saucy 5e019ab7bf6d 4 weeks ago 180 MB
ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB
ubuntu precise 74fe38d11401 4 weeks ago 209.6 MB
ubuntu 12.10 a7cf8ae4e998 4 weeks ago 171.3 MB
ubuntu quantal a7cf8ae4e998 4 weeks ago 171.3 MB
ubuntu 14.04 99ec81b80c55 4 weeks ago 266 MB
ubuntu latest 99ec81b80c55 4 weeks ago 266 MB
ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
ubuntu 13.04 316b678ddf48 4 weeks ago 169.4 MB
ubuntu raring 316b678ddf48 4 weeks ago 169.4 MB
ubuntu 10.04 3db9c44f4520 4 weeks ago 183 MB
ubuntu lucid 3db9c44f4520 4 weeks ago 183 MB
ここで表示されるのは、これまでの user guide で作成したものです。
それぞれ、対象となるイメージを起動しようとした時、Docker Hub からダウンロードしてきたものです。
この一覧では、3つの重要なイメージの情報が表示されています。
- どのレポジトリからのものか。例えば
ubuntu
- 各々のイメージのタグ。例えば
14.04
- イメージのイメージ ID
レポジトリは複数の種類のイメージを持っている可能性があります。私たちの ubuntu
イメージの場合は、Ubuntu 10.04, 12.03, 12.10, 13.04, 13.10, 14.04 のように、私たちは複数のバージョンを扱っていることが分かります。各々のイメージはタグで識別することができ、次のように表示されます。
ubuntu:14.04
コンテナを実行しようとするとき、タグ付けされたイメージを指定するには、次のようにします:
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
替わりに 12.04 のイメージを使って構築したい場合は、次のようにします:
$ sudo docker run -t -i ubuntu:12.04 /bin/bash
バージョンを明示して指定しない場合、例えば ubuntu
とだけ指定した場合は、デフォルトで ubuntu:latest
イメージを使用します。
注:私たちは常に特定のタグを付けたイメージの使用を推奨します。例えば ubuntu:12.04
のようにです。これによって、イメージのどのようなバージョンが使われているか、常に厳密に分かるからです。
新しいイメージの取得
それでは、新しいイメージを取得するときはどうしたら良いでしょうか。Docker は、Docker ホスト上に存在しないあらゆるイメージを、自動的にダウンロードします。しかしながら、場合によってはコンテナを起動するのに少々の時間がかかってしまう場合があります。もし、予めイメージの事前読み込みをしたければ、docker pull
コマンドを使って事前ダウンロードをすることが出来ます。それでは、centos
イメージをダウンロードしてみましょう。
$ sudo docker pull centos
Pulling repository centos
b7de3133ff98: Pulling dependent layers
5cc9e91966f7: Pulling fs layer
511136ea3c5a: Download complete
ef52fb1fe610: Download complete
. . .
各々のレイヤのイメージがプルダウンされ、このイメージからコンテナを実行できるようになりましたので、イメージをダウンロードするために待つ必要はありません。
$ sudo docker run -t -i centos /bin/bash
bash-4.1#
イメージの検索
Docker の特長の1つに、沢山の人が作成した様々な Docker イメージがあります。大部分は Docker Hub にアップロードされています。これらのイメージは Docker Hub のウェブサイトから検索する事が出来ます。
画像 http://docs.docker.com/userguide/search.png
または、docker search
コマンドを使って、コマンドラインからイメージを検索することもできます。例えば、私たちが欲しいイメージは、ウェブアプリケーション開発のために Ruby と Sinatra がインストールされているものとします。私たちはイメージを docker search
コマンドを使って sinatra
という言葉を含むイメージを探すことができます。
$ sudo docker search sinatra
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
training/sinatra Sinatra training image 0 [OK]
marceldegraaf/sinatra Sinatra test app 0
mattwarren/docker-sinatra-demo 0 [OK]
luisbebop/docker-sinatra-hello-world 0 [OK]
bmorearty/handson-sinatra handson-ruby + Sinatra for Hands on with D... 0
subwiz/sinatra 0
bmorearty/sinatra 0
. . .
実行すると sinatra
という言葉を含む沢山のイメージの情報が表示されます。表示されるのは、NAME(イメージ名)、DESCRIPTION(説明)、STAR(スター数)(イメージがソーシャル上で有名である指標 - 利用者がイメージが好きなら "star" することができます)、そして、OFFICIAL (公式かどうか)、AUTOMATED(自動ビルド)の状態です。
公式レポジトリとは、Stackbrew プロジェクトによって構築と監視されたもので、自動ビルドされた自動化されたレポジトリにあり、これによって、出所(source)とイメージの中身の安全性を確認します。
さて、利用可能なイメージの中から training/sinatra
イメージを使う事を決めました。次に私たちは ubuntu
のようなイメージ(base イメージまたは root イメージと呼んでいます)を使うため、2種類のイメージリポジトリを参照します。ベースイメージは Docker 社が構築し、提供しているものであり、有効性が保証されています。これによって、単語名から(イメージを)識別することができます。
私たちが選んだ training/sinatra
イメージのように、ユーザイメージの探し方を見て来ました。ユーザイメージは、Docker コミュニティのメンバーに所属するもので、ユーザ自身によって管理されているものです。ユーザイメージを、ユーザ名のプレフィックス、ここでは training
というユーザ名がイメージを作成したのかという情報を識別することができます。
私たちのイメージをもってくる(pull)
私たちは適切なイメージ training/sinatra
を確認し、これで docker pull
コマンドを使ってダウンロードすることができます。
$ sudo docker pull training/sinatra
これで、チームはこのイメージを使って、それぞれのコンテナを実行できるようになります。
$ sudo docker run -t -i training/sinatra /bin/bash
root@a8cb6ce02d85:/#
私たちのイメージの作成
チームでは training/sinatra
イメージが有用であるとわかりましたが、イメージを私たちの欲しいものにするためには、いくつかの変更を加える必要があることがわかりました。
- 私たちはイメージからコンテナの更新を行う事が出来、変更点をイメージにコミット出来ます。
- 私たちはイメージの作成にあたり 'Dockerfile' を用いて細かな指示を行えます。
コミットしたイメージの更新
イメージを更新するには、まず、更新したいイメージからコンテナを作成する必要があります。
$ sudo docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/#
注:作成された 0b2616b0e5a8
というコンテナ ID を記録しておきます。この後すぐに使います。
実行しているコンテナの中で json
gem をインストールしましょう。
root@0b2616b0e5a8:/# gem install json
作業が終わったら、exit
コマンドを実行してコンテナから抜けます。
これで、私たちが欲しい変更を加えたコンテナが手に入りました。docker commit
コマンドを対象のイメージに使う事で、このコンテナのコピーにコミットすることができます。
$ sudo docker commit -m="Added json gem" -a="Kate Smith" \
0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
ここで docker commit
コマンドを使いました。-m
と -a
、2つのフラグを指定しています。-m
フラグは、バージョンコントロールシステムにコミットするような、コミットメッセージを明示できます。-a
フラグは、更新に当たっての作者を指定するものです。
そしてまた、私たちが新しいコンテナの作る元も 0b2616b0e5a8
のように指定します(コンテナ ID は先に記録したものです)。そして、イメージに次のように指定します。
ouruser/sinatra;v2
それでは詳細を見ていきましょう。ouruser
は新しいユーザ名の指定で、このイメージを書いた人です。また、イメージに特定の名前も指定します。ここではオリジナルのイメージ名は sinatra
です。最後にイメージに対するタグを v2
と指定します。
それから、docker images
コマンドを使うと、新しく ouruser/sinatra
イメージが作成されます。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
training/sinatra latest 5bc342fa0b91 10 hours ago 446.7 MB
ouruser/sinatra v2 3c59e02ddd1a 10 hours ago 446.7 MB
ouruser/sinatra latest 5db5f8471261 10 hours ago 446.7 MB
```
新しく作成したイメージを元にコンテナを使うには、次のようにします。
```
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@78e82f680994:/#
```
### `Dockerfile` からイメージを作成する。
`docker commit` コマンドを使うことは、イメージを拡張するための簡単な方法ですが、少々煩わしく、チーム間でイメージを開発プロセスにおいて共有するのは簡単ではありません。スクラッチで(ゼロから)新しいイメージを作る代わりに、私たちは `docker build` という新しいコマンドを使うことができます。
実行する為には `Dockerfile` を作成し、Docker に対してどのようにイメージを構築するかの命令セットを記述しています。
それでは、まずディレクトリを作成し、`Dockerfile` を置きましょう。
```
$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile
```
それぞれの命令を含む新しいイメージの層を作成します。私たちの開発チームが、自分たち自身の Sinatra イメージを新しく作る場合の例を考えて見ましょう。
```
# This is a comment
FROM ubuntu:14.04
MAINTAINER Kate Smith <ksmith@example.com>
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra
```
それでは、'Dockerfile' は何をしているか見ていきましょう。各々の指示のプリフィクスは、命令文であり、大文字で書きます。
```
INSTRUCTION statement
命令 命令文
```
注:`#` をコメントとして表示する事ができます
最初の命令 `FROM` は、Docker に対してソースとなるイメージは何かを伝え、この場合は私たちは Ubuntu 14.04 イメージの上の新規イメージを基盤とする事を伝えます。
次に `MAINTAINER` 命令を使って、誰が新しいイメージを管理するのか明示します。
最後に、3つの `RUN` 命令を記述します。`RUN` 命令は、イメージの中で実行するコマンドを書きます。例えばパッケージをインストールするなど。ここでは APT キャッシュの更新を行い、Ruby と RubyGems をインストールした後、Sinatra gem をインストールします。
注:Dockerfile で[利用可能な命令は、もっと沢山あります](http://docs.docker.com/reference/builder)。
それでは、`Dockerfile` を使って、`docker build` コマンドによってイメージを構築してみましょう。
```
$ sudo docker build -t="ouruser/sinatra:v2" .
Uploading context 2.56 kB
Uploading context
Step 0 : FROM ubuntu:14.04
---> 99ec81b80c55
Step 1 : MAINTAINER Kate Smith <ksmith@example.com>
---> Running in 7c5664a8a0c1
---> 2fa8ca4e2a13
Removing intermediate container 7c5664a8a0c1
Step 2 : RUN apt-get -qq update
---> Running in b07cc3fb4256
---> 50d21070ec0c
Removing intermediate container b07cc3fb4256
Step 3 : RUN apt-get -qqy install ruby ruby-dev
---> Running in a5b038dd127e
Selecting previously unselected package libasan0:amd64.
(Reading database ... 11518 files and directories currently installed.)
Preparing to unpack .../libasan0_4.8.2-19ubuntu1_amd64.deb ...
. . .
Setting up ruby (1:1.9.3.4) ...
Setting up ruby1.9.1 (1.9.3.484-2ubuntu1) ...
Processing triggers for libc-bin (2.19-0ubuntu6) ...
---> 2acb20f17878
Removing intermediate container a5b038dd127e
Step 4 : RUN gem install sinatra
---> Running in 5e9d0065c1f7
. . .
Successfully installed rack-protection-1.5.3
Successfully installed sinatra-1.4.5
4 gems installed
---> 324104cde6ad
Removing intermediate container 5e9d0065c1f7
Successfully built 324104cde6ad
```
`docker build` コマンドを使う事によって、`-t` フラグで新しく `ouruser` に所属するイメージを作成し、`sinatra` という名前のレポジトリで、`v2` というタグを使用します。
また、私たちは `Dockerfile` を `.` で指示しており、これは現在のディレクトリにある `Dockerfile` を使うようにしています。
注:`Dockerfile` のパスを明示することもできます。
これで動作時の構築プロセスを見る事ができました。まず Docker が行っているのは、構築のコンテキスト(環境)をアップロードすることです。基本的に構築しようとしているディレクトリの中にコンテンツを置きます。これは Docker デーモンが実際にイメージを構築し、ローカルなコンテキストをそこに入れるために必要となるからです。
次に、`Dockerfile` の指示は、段階的に実行するのを見る事が出来ます。
新しいコンテナを構築する各々のステップに於いて、
コンテナの中に対して命令を出し、
そして、これまでみてきたような `docker commit` ワークフローのようにコンテナに対する変更をコミットします。
全ての命令が `324104cde6ad` というイメージに対して実行され(あるいは、タグ付けされて分かりやすい `ouruser/sinatra:v2`)、中間コンテナは削除されます。
これで、私たちは私たちの新規イメージからコンテナを起動できます。
```
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@8196968dac35:/#
```
注:これは最短でイメージを作るための導入です。私たちは、利用可能な命令の全てを使っているわけではありません。更に多くの命令はガイドの後半でお見せしますし、あるいは、`Dockerfile` リファレンスを参照して、全ての命令に関する説明や例を読む事ができます。
## イメージにタグを付ける
コミットやビルド後でも、既存イメージに対するタグを追加することができます。そのためには `docker tag` コマンドを使います。それでは `ouruser/sinatra` イメージに対して新しいタグを付けます。
```
$ sudo docker tag 5db5f8471261 ouruser/sinatra:devel
```
`docker tag` コマンドにはイメージの ID を渡します、ここでは `5db5f8471261` であり、そこに私たちのユーザ名と、レポジトリ名(ここでは devel)という新しいタグを追加します。
`docker images` コマンドで新しいタグの情報を見てみましょう。
```
$ sudo docker images ouruser/sinatra
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ouruser/sinatra latest 5db5f8471261 11 hours ago 446.7 MB
ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB
ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB
```
## Docker Hub にイメージを送る(push)
構築した新しいイメージは、`docker push` コマンドを使う事で、[Docker Hub](https://hub.docker.com/) に push することができます。これは、他人と共有したり、公開したりできますし、あるいは[プライベートなレポジトリ](https://registry.hub.docker.com/plans/)に送ることもできます。
## ホストからイメージを削除する
Docker ホストから `docker rmi` コマンドで、コンテナの使っているイメージを削除することもできます。
`training/sinatra` イメージがもう必要なければ、削除してみましょう。
```
$ docker rmi training/sinatra
Untagged: training/sinatra:latest
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
```
注:イメージをホストから削除するためには、ベースとして使っているコンテナが存在していない必要があります。
## 次のステップ
これまで、どのように個々のアプリケーションを Docker コンテナの中に構築するかを見て来ました。次は、どのように複数の Docker コンテナがスタックされているアプリケーションで、Docker を構築するかを学びます。
Go to [Linking Containers Together](http://docs.docker.com/userguide/dockerlinks).