Dockerイメージに関するもう少し詳しい説明


 Dockerの仮想環境であるDockerコンテナは、起動時にDockerイメージを指定します。そのイメージは、コンテナのベースとなるOSであったり、Webなどのサービスが構築済みであったりと様々だと思いますが、必ずDockerイメージが必要です。

 DockerにとってDockerイメージはとても重要で、構成次第では構築するシステムにかなりの影響をもたらすものだと私は考えます。

 本記事を読んでいただくことで、そんなDockerイメージをもう少し詳しくご理解いただくきっかけになればと思っております。

Dockerイメージについての詳細説明

 Dockerイメージは、Dockerコンテナの雛形となるファイル群です。Dockerイメージの中には、仮想環境の初期状態のディスクイメージが格納されてます。Dockerの仮想環境であるDockerコンテナは、このDockerイメージを基に起動されます。

 このDockerイメージに関して、もう少し詳細に見ていきたいと思います。

 

読み込み専用で複数レイヤ構成のDockerイメージ

 Dockerイメージは、Dockerコンテナが使用するディスクに相当するものなのですが、実は読み込み専用(リードオンリー)となってます。

 更に、Dockerイメージは、イメージレイヤと呼ばれる、これまた読み込み専用のディスク更新イメージを複数積み重ねて作られてます。

 以下は、Ubuntuバージョン16.04のDockerイメージを入手した際の出力内容です。

$ docker pull ubuntu:16.04
Using default tag: latest
16.04: Pulling from library/ubuntu
952132ac251a: Pull complete
82659f8f1b76: Pull complete
c19118ca682d: Pull complete
8296858250fe: Pull complete
24e0251a0e2c: Pull complete
Digest: sha256:f4691c96e6bbaa99d99ebafd9af1b68ace2aa2128ae95a60369c506dd6e6f6ab
Status: Downloaded newer image for ubuntu:16.04

 出力内容に、952132ac251a、82659f8f1b76、c19118ca682d、8296858250fe、24e0251a0e2cの文字列がありますが、この1つ1つがイメージレイヤになります。この複数のイメージレイヤを1つに合わせて、Ubuntuバージョン16.04のDockerイメージ「ubuntu:16.04」として利用します。

 

Dockerイメージの作成履歴をDockerコマンドで見る方法

 Dockerfileを使用して、あるDockerイメージをベースイメージとして、新たなDockerイメージを作成した場合は、ベースとして利用したDockerイメージのレイヤに新たなイメージレイヤが追加されることになります。

 Dockerコマンドに「docker history」というものがありますが、これは、Dockerイメージの作成履歴を出力するコマンドです。このコマンドを使用して、実際にDockerイメージのイメージレイヤを覗いてみたいと思います。

 UbuntuのDockerイメージを使用して確認してみます。

 まずは、公式のUbuntuのDockerイメージを入手します。

$ docker pull ubuntu:16.04

 バージョン16.04を決めうちで入手してみました。早速「docker history」コマンドで確認してみます。

$ docker history ubuntu:16.04

以下のように出力されたと思います。

IMAGE         CREATED      CREATED BY                          SIZE COMMENT
bd3d4369aebc  4 days ago   /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing>     4 days ago   /bin/sh -c mkdir -p /run/systemd && echo 'doc 7 B
<missing>     4 days ago   /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/ 1.895 kB
<missing>     4 days ago   /bin/sh -c rm -rf /var/lib/apt/lists/* 0 B
<missing>     4 days ago   /bin/sh -c set -xe && echo '#!/bin/sh' > /u 745 B
<missing>     4 days ago   /bin/sh -c #(nop) ADD file:902bff94e00fb3d9eb 126.6 MB

 一番左はイメージレイヤのIDになります。

 「<missing>」となっている部分は、以前(Docker ver1.10未満)は全ての情報が出力されていたのですが、バージョン1.10からDockerのストレージに関する仕様が変更になり、表示されない箇所も出てくるようになってきました。

 とりあえず、6層分のイメージレイヤがあることが解ります。

 

 これを踏まえて、今入手したUbuntuのDockerイメージにイメージレイヤを追加してみたいと思います。

 任意の空のディレクトリを作成し、そのディレクトリ内に、以下の内容のDockerfileを作成します。

FROM ubuntu:16.04

RUN echo "Hello world" > /usr/helloworld.txt

 2行目の「RUN」は、使用するDockerイメージ(今回はUbuntuバージョン16.04)に対して、「"Hello world" > /usr/helloworld.txt」を実行する命令になります。この命令によって、「/usr/helloworld.txt」が作成され、Dockerイメージが更新されることになります。

 

 次に、Dockerfileを作成したディレクトリをカレントディレクトリとして、以下のDockerコマンドを実行します。

$ docker build --rm -t testimages .

 以下のような内容が出力されます。

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu:16.04
 ---> bd3d4369aebc
Step 2 : RUN echo "Hello world" > /usr/helloworld.txt
 ---> Running in 10196cb4b7fb
 ---> 6d71c7c98d2d
Removing intermediate container 10196cb4b7fb
Successfully built 6d71c7c98d2d

 上の内容を簡単に説明します。

 まずStep1でベースイメージとなる「ubuntu:16.04」が表示されてます。

 このDockerイメージがローカルのイメージ格納場所に存在しない場合は、DockerHUBから入手する処理が行われるのですが、既に入手済みの場合は行われません。

 Step1の次の行に「---> bd3d4369aebc」が出力されてます。

 ここで、「docker images」コマンドを実行してください。

$ docker images
REPOSITORY      TAG       IMAGE ID         CREATED       SIZE
ubuntu          16.04     bd3d4369aebc     4 days ago    126.6 MB

 ubuntuバージョン16.04のイメージIDは「bd3d4369aebc」であることが解りました。

 これはstep1で表示されたイメージレイヤのIDと同じです。

 よって、先ほど入手したUbuntuのDockerイメージが使われていることが解ります。

 次にstep2として、Dockerfileに記載した「RUN」命令が出力されてます。これによって、ベースイメージの更新が行われ、新しいID「6d71c7c98d2d」が付与されていることが解ります。

 最後に「Successfully built 6d71c7c98d2d」と出力されてますが、「RUN」命令で付与されたIDと同じですね。

 最終的に付与されたイメージIDが、作成したDockerイメージのイメージIDになるようです。

 

 では、作成した新しいDockerイメージを確認してみたいと思います。

 まずは、「docker images」コマンドです。

$ docker images
REPOSITORY     TAG      IMAGE ID        CREATED           SIZE
testimages     latest   6d71c7c98d2d    16 minutes ago    126.6 MB
ubuntu         16.04    bd3d4369aebc    4 days ago        126.6 MB

 「docker build」コマンドで指定した「testimages」が作成されていることが確認できます。

 次に「docker history」コマンドで「testimages」を確認してみましょう。

$ docker history testimages
IMAGE        CREATED        CREATED BY                    SIZE COMMENT
6d71c7c98d2d 21 minutes ago /bin/sh -c echo "Hello world" > /usr/hellowor 12 B
bd3d4369aebc 4 days ago     /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing>    4 days ago     /bin/sh -c mkdir -p /run/systemd && echo 'doc 7 B
<missing>    4 days ago     /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/ 1.895 kB
<missing>    4 days ago     /bin/sh -c rm -rf /var/lib/apt/lists/* 0 B
<missing>    4 days ago     /bin/sh -c set -xe && echo '#!/bin/sh' > /u 745 B
<missing>    4 days ago     /bin/sh -c #(nop) ADD file:902bff94e00fb3d9eb 126.6 MB

 一番上の行のイメージレイヤIDは「6d71c7c98d2d」と出力されてます。

 先ほど「docker build」を行った際の出力内容を再度確認してください。step2で出力されたIDと同じであることが確認できると思います。

 また、「RUN」命令で指定した内容も出力されていることも確認できます。

 

 更に、上記出力内容の「6d71c7c98d2d」の行の次の行から下の内容と、前に確認したUbuntuのDockerイメージの「docker history」の出力内容を確認してみてください。

 全く同じですね。

 

 このことから、最初に入手したUbuntuのDockerイメージに、Dockerfileを使用して更新した新しいイメージレイヤが追加されて、新しいDockerイメージが作成されていることが解ると思います。

 このように、Dockerイメージは、更新したい内容のイメージレイヤを積み重ねて新しいDockerイメージを作成していくことになります。

 

今回はここまでです。

最後までお読みいただいてありがとうございました。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください