Dockerイメージの入手

2015年9月1日(火)
古賀 政純

Dockerが誕生する前から、コンテナ型のシステムを使用していた運用担当者や開発者は、それほど違和感なくDockerを使うことができますが、全くDockerを使用したことがない未経験者やハイパーバイザー型の仮想化ソフトウェアだけの経験者からすると、Dockerの使用感は、独特に感じるかもしれません。特に、コンテナのプロセスとしての考え方、イメージファイルの作成、ディスクの共有方法、バックアップやリストア手順、ネットワーク、GUIアプリケーションの起動方法などは、通常の物理サーバーやハイパーバイザー型の仮想化ソフトウェアのゲストOSの管理と大きく異なる点も少なくありません。最初は、戸惑うことが多いかもしれませんが、本連載では、目的別に具体的例をできるだけ用意しましたので、実際に手を動かし、理解を深めてください。では、いよいよ、Dockerによるコンテナ管理の世界へ飛び込みます。

Dockerを使う上で知っておくべき各種コンポーネント

Dockerでは、様々なOSとアプリケーションがパッケージ化された環境がDockerハブと呼ばれるリポジトリに用意されています。Dockerハブは、「Dockerハブ・レジストリ」とも呼ばれ、ユーザーは、インターネットを経由してOS環境とアプリケーションを含んだイメージを入手します。このイメージは、一般的に,「Dockerイメージ」と呼ばれます。Dockerイメージは、ベースイメージとも呼ばれており、Linux OSとアプリケーションを含んだ一種のテンプレートです。Dockerのリポジトリには、世界中のユーザーや開発者が作成したDockerイメージが大量に保管されています。ユーザーがイメージを一から作成することも可能ですが、すでにDockerハブに用意されているイメージをそのまま利用することができますので、OSやアプリケーションのインストールや初期設定等に係る煩雑な作業工数を大幅に削減することができます。

世界中のユーザーや開発者は、OSとアプリケーションをパッケージ化したものをイメージとしてDockerハブに登録していますが、一方、インターネットを使わず、ローカルのシステムに保管したイメージのリポジトリは、「Dockerプライベート・レジストリ」と呼ばれます。ローカルのシステムにおいて、OSとアプリケーションのパッケージ化や、イメージを使ったコンテナの実行は、Dockerの本体が担います。このDockerの本体は、一般的に「Docker Engine」と呼ばれます。Docker Engineが実行するコンテナは、「Docker Container」と呼ばれます。Docker Containerは、ホストOS上で複数同時に起動させることができ、ホストOSから見ると分離された名前空間として見えます。一般的に、ユーザーは、Dockerデーモンが稼働するホストOS上でコマンドラインから操作を行いますが、このDockerデーモンへの操作を担う各種コマンド等のインタフェースは、「Docker Client」と呼ばれます。Docker Clientは、Dockerデーモンが稼働するホストOS上でコマンドライン操作が可能ですが、遠隔地にあるDockerデーモンと通信を行うことも可能です。

Dockerエンジンアプリケーションのパッケージ化やコンテナの実行を担う
DockerイメージOSやアプリケーションを含んだテンプレートのベースイメージ
Dockerハブ・レジストリ公開されているDockerイメージをSaaS経由で提供する
Dockerプライベート・レジストリローカルで作成・保管したイメージのリポジトリ
Dockerコンテナ分離された名前空間とアプリケーションの実行環境
Dockerクライアントユーザーがコマンドを発行し、Dockerデーモンと通信を行う

[補足]

SaaS(Software-as-a-Service):ソフトウェアをサービスとして提供するクラウド基盤。

Dockerの各種コンポーネント

図1:Dockerの各種コンポーネント

Dockerの使用法

以下では、CentOS 7.xで稼働するDockerの具体的な使用法について説明します。インターネット経由でDockerイメージを入手し、そのイメージからコンテナを生成、起動してみましょう。まず、Docker Hubで用意されているDockerイメージを入手します。Dockerイメージの入手は、dockerコマンドにpullを付与し、そのあとにイメージ名を指定します。以下は、CentOS 7.1のイメージである「centos:centos7.1.1503」を入手する例です。

# docker pull centos:centos7.1.1503

ローカルのCentOS 7.xサーバー上に保管されているDockerイメージを確認してみます。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/centos    centos7.1.1503      f1dade627e25        3 weeks ago         212.1 MB

同様に、CentOS 5.11、CentOS 6.6、Ubuntu 14.04.1のDockerイメージを入手してみましょう。

# docker pull centos:centos5.11
# docker pull centos:centos6.6
# docker pull ubuntu:14.04.1

入手したイメージ一覧を確認します。Dockerイメージの確認は、dockerコマンドに「images」を付与します。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/centos    centos5.11          223843a319ca        3 weeks ago         284.1 MB
docker.io/centos    centos6.6           8b44529354f3        3 weeks ago         202.6 MB
docker.io/centos    centos7.1.1503      f1dade627e25        3 weeks ago         212.1 MB
docker.io/ubuntu    14.04.1             5ba9dab47459        3 months ago        188.3 MB

Dockerイメージの一覧では、リポジトリ、タグ、イメージID、作成日、イメージのサイズが表示されます。

Dockerコンテナの起動

ユーザーは、タグと呼ばれる名前を使ってコンテナの起動などの操作を行います。イメージIDは、Dockerが管理する番号で、管理者は、このIDを使ってDockerイメージの管理を行います。上記のイメージファイル群のうち、今回、centos6.6という名前の付いたタグの付いたDockerイメージから、コンテナを生成、起動し、そのコンテナ内で作業できるようにしてみましょう。コンテナの起動はdockerコマンドに「run」を付与します。

# docker run --name test01 -i -t centos:centos6.6  /bin/bash

以下、DockerイメージからDockerコンテナを生成、起動すときの主なオプションです。

--nameオプション作成するコンテナに名前を付ける
-iオプションDockerコンテナ起動時に、標準入力(STDIN)を保つようにする
-tオプション仮想端末(pseudo-TTY)をコンテナに割り当てる

今回は、「--name」オプションにtest01 を付与しているので、コンテナの名前はtest01となります。centos:centos6.6を指定していますので、先程入手しローカルに保管されているCentOS 6.6のDockerイメージからコンテナを生成、起動することになります。上記のコマンドを発行すると、以下のようなbashプロンプトが表示されるはずです。

[root@bbf6e5f357e1 /]#

ここで、プロンプトに注目してください。「root@」のあとに文字列が並んでいます。この文字列は、Dockerが自動的に割り当てたコンテナIDを示しています。このコンテナIDは、個々のシステムによって異なります。

引き続き、プロンプトが、「[root@bbf6e5f357e1 /]#」となっている端末で作業してみます。コンテナのOSのバージョンを確認します。

[root@bbf6e5f357e1 /]# cat /etc/redhat-release
CentOS release 6.6 (Final)
[root@bbf6e5f357e1 /]#

すると、CentOS 6.6であることがわかります。コンテナのホスト名を確認してみます。

[root@bbf6e5f357e1 /]# hostname
bbf6e5f357e1
[root@bbf6e5f357e1 /]#

ホスト名は自動的に「bbf6e5f357e1」という名前で割り振られていることがわかります。これは、Dockerが初期状態でコンテナIDをホスト名にするように設定されているためです。ホスト名は、Dockerコンテナ起動時に明示的に指定することも可能です。さらに、現在作業中のコンテナのIPアドレスを確認し、ホストOSや外部と通信できるかを確認します。

[root@bbf6e5f357e1 /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
4: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:01 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:1/64 scope link
       valid_lft forever preferred_lft forever
[root@bbf6e5f357e1 /]#

[root@bbf6e5f357e1 /]# ping -c 3 172.16.1.1
PING 172.16.1.1 (172.16.1.1) 56(84) bytes of data.
64 bytes from 172.16.1.1: icmp_seq=1 ttl=254 time=0.892 ms
64 bytes from 172.16.1.1: icmp_seq=2 ttl=254 time=1.05 ms
64 bytes from 172.16.1.1: icmp_seq=3 ttl=254 time=1.18 ms

--- 172.16.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2018ms
rtt min/avg/max/mdev = 0.892/1.042/1.186/0.125 ms
[root@bbf6e5f357e1 /]#

[root@bbf6e5f357e1 /]# nslookup www.hp.com
...
[root@bbf6e5f357e1 /]#

作業中のCentOS 6.6のDockerイメージに、なにか適当なファイルを作成してみましょう。

[root@bbf6e5f357e1 /]# echo “Hello Docker” > /root/testfile0001
[root@bbf6e5f357e1 /]# ls /root/
testfile0001

作業中のDockerコンテナのCentOS 6.6の環境から離脱します。作業中のコンテナのコマンドラインから離脱するには、exitコマンドを使います。

[root@bbf6e5f357e1 /]# exit
exit
#

これで、ホストOS(Dockerエンジンが稼働するCentOS 7.x)のプロンプトに戻ったはずです。ホストOS上で、過去に起動したコンテナ一覧を確認してみましょう。コンテナ一覧は、そのコンテナが起動中かどうかにかかわらず、dockerコマンドに「ps -a」を付与することで確認することができます。

# docker ps -a
CONTAINER ID   IMAGE             COMMAND      CREATED        ...    NAMES
bbf6e5f357e1   centos:centos6.6  "/bin/bash" 16 minutes ago  ...    test01

Dockerイメージを作成する

先程、/root/testfile0001を作成したコンテナを再利用できるように、コンテナのイメージ化を行います。コンテナをイメージ化するには、Dockerコマンドに「commit」を付与し、コンテナをコミットします。先程作業したコンテナのコンテナIDとイメージを指定してコミットを行います。コンテナIDは、先述の「docker ps -a」で得られる「CONTAINER ID」に示された文字列を指定し、コンテナのイメージのタグを付けます。今回、タグは、ホスト名がわかるように「centos:c66docker0001」を付与することにします。

# docker commit bbf6e5f357e1 centos:c66docker0001
adfb14925cf6abce034ba15c629838582a215716a47c6dbde9d48631404a20e1
#

Dockerコンテナが、コミットされると、イメージとしてローカルに保管されます。作成したDockerイメージ「centos:c66docker0001」が保管されているか、現在のイメージの一覧を確認します。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              c66docker0001       adfb14925cf6        56 seconds ago      202.6 MB
docker.io/centos    centos5.11          223843a319ca        3 weeks ago         284.1 MB
docker.io/centos    centos6.6           8b44529354f3        3 weeks ago         202.6 MB
docker.io/centos    centos7.1.1503      f1dade627e25        3 weeks ago         212.1 MB
docker.io/ubuntu    14.04.1             5ba9dab47459        3 months ago        188.3 MB
#

Dockerイメージとして、「centos:c66docker0001」が保管されていることがわかります。コミットしたDockerイメージ「centos:c66docker0001」を使って、別のコンテナtest02を生成、起動してみます。

# docker run --name test02 -i -t centos:c66docker0001 /bin/bash

コンテナtest02上の/rootを確認してみます。

[root@3697292040fd /]# ls /root/
testfile0001
[root@3697292040fd /]#

今度は、現在作業中のコンテナtest02で、/root/testfile0002を作成します。

[root@3697292040fd /]# echo "Hello Docker Docker" > /root/testfile0002
[root@3697292040fd /]# ls /root/
testfile0001  testfile0002
[root@3697292040fd /]#

これで、/rootディレクトリに、testfile0001とtestfile0002が存在する状態になりました。コンテナtest02から離脱し、ホストOS上で、コンテナの状態を確認します。

# docker ps -a
CONTAINER ID   IMAGE                  COMMAND        CREATED          ...    NAMES
3697292040fd   centos:c66docker0001   "/bin/bash"    3 minutes ago    ...    test02
ef9be65776cc   centos:centos6.6       "/bin/bash"    5 minutes ago    ...    test01

コンテナtest01は、CentOS 6.6のベースイメージ、コンテナtest02は、Dockerイメージ「centos:c66docker0001」がもとになっていることがわかります。先程作業した、コンテナtest02をコミットし、新たなDockerイメージ「c66docker0002」を作成します。

# docker commit 3697292040fd centos:c66docker0002
63a6ffd5c00b440ea16e2c027ca7eaf694a0a8eaff7a19a491881efc04dd623

Dockerイメージ「centos:c66docker0002」が作成されたかを確認します。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              c66docker0002       63a6ffd5c00b        41 seconds ago      202.6 MB
centos              c66docker0001       adfb14925cf6        9 minutes ago       202.6 MB
docker.io/centos    centos5.11          223843a319ca        3 weeks ago         284.1 MB
docker.io/centos    centos6.6           8b44529354f3        3 weeks ago         202.6 MB
docker.io/centos    centos7.1.1503      f1dade627e25        3 weeks ago         212.1 MB
docker.io/ubuntu    14.04.1             5ba9dab47459        3 months ago        188.3 MB

上記より、Dockerイメージ「c66docker0001」とは別の新たなDockerイメージ「c66docker0002」が保管されていることがわかります。Dockerイメージ「c66docker0001」と「c66docker0002」からコンテナを起動し、それぞれの/rootディレクトリの様子を見えてみましょう。

# docker run --name test03 -i -t centos:c66docker0001 /bin/bash
[root@fbcbaec55d95 /]# ls /root/
testfile0001
[root@fbcbaec55d95 /]# exit
exit

# docker run --name test04 -i -t centos:c66docker0002 /bin/bash
[root@626be4ec0133 /]# ls /root/
testfile0001  testfile0002
[root@626be4ec0133 /]# exit
exit
#

作業を行ったコンテナをコミットすることでその作業内容を反映したイメージファイルが生成でき、さらに作成したイメージファイルを再利用して、新たなコンテナを生成し作業できることがわかります。開発者は、アプリケーション毎に異なるコンテナを複数作成し、コミットしておけば、そのアプリケーションに特化したイメージファイルを持つことができ、すぐにアプリケーションが実行可能な環境をコンテナで再利用することができます。

ホストマシンに保管されたDockerイメージからdocker runでコンテナを起動する。起動したコンテナで作業を施し、アプリケーション等の構築をしたものをdocker commitでDockerイメージとして登録する

図2:Dockerイメージとコンテナ.png(図の説明:ホストマシンに保管されたDockerイメージからdocker runでコンテナを起動する。起動したコンテナで作業を施し、アプリケーション等の構築をしたものをdocker commitでDockerイメージとして登録する)

今まで、起動してはexitしたコンテナがどうなっているかを確認してみましょう。

# docker ps -a
CONTAINER ID  IMAGE                 COMMAND      ...  STATUS                         ...   NAMES
626be4ec0133  centos:c66docker0002  "/bin/bash"  ...  Exited (0) About a minute ago  ...   test04
fbcbaec55d95  centos:c66docker0001  "/bin/bash"  ...  Exited (0) 2 minutes ago       ...   test03
3697292040fd  centos:c66docker0001  "/bin/bash"  ...  Exited (0) 9 minutes ago       ...   test02
ef9be65776cc  centos:centos6.6      "/bin/bash"  ...  Exited (0) 14 minutes ago      ...   test01

これらのコンテナtest01、test02、test03、そしてtest04の状態「STATUS」を見えると、「Exited」となっており、コンテナが終了していることがわかります。

[補足] 「docker images」のオプション

DockerのイメージIDは、標準で、12文字で表示されますが、本来のイメージIDは、64文字で表されます。本来の64文字のイメージIDを表示させるには、「--no-trunc」オプションを付与します。

# docker images --no-trunc
REPOSITORY   TAG             IMAGE ID                                                           CREATED      VIRTUAL SIZE
centos       c66docker0001   5cd00a3618953508c4846ed750a6ffb6153e5ae46eae6f02e63c7b90fa055132   2 days ago   202.6 MB
centos       c66docker0002   63a6ffd5c00b440ea16e2c027ca7eaf694a0a8eaff7a19a491881efc04dd6237   2 days ago   202.6 MB

また、イメージIDのみを出力させたい場合もあります。その場合は、-qオプションを付与します。

# docker images --no-trunc -q
5cd00a3618953508c4846ed750a6ffb6153e5ae46eae6f02e63c7b90fa055132
63a6ffd5c00b440ea16e2c027ca7eaf694a0a8eaff7a19a491881efc04dd6237

Dockerコンテナの削除

Dockerイメージさえあれば、いつでもコンテナを生成できますので、終了したコンテナを削除しておきましょう。コンテナの削除は、dockerコマンドに「rm」を付与し、コンテナIDを指定します。ここでは、上記すべてのコンテナを削除してみましょう。

# docker rm 626be4ec0133 fbcbaec55d95 3697292040fd ef9be65776cc
626be4ec0133
fbcbaec55d95
3697292040fd
ef9be65776cc

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
#

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              c66docker0002       63a6ffd5c00b        46 minutes ago      202.6 MB
centos              c66docker0001       adfb14925cf6        54 minutes ago      202.6 MB
docker.io/centos    centos5.11          223843a319ca        3 weeks ago         284.1 MB
docker.io/centos    centos6.6           8b44529354f3        3 weeks ago         202.6 MB
docker.io/centos    centos7.1.1503      f1dade627e25        3 weeks ago         212.1 MB
docker.io/ubuntu    14.04.1             5ba9dab47459        3 months ago        188.3 MB

コンテナは削除されていますが、イメージは削除されずに保管されていることを確認してください。

[補足] コンテナIDをシェル変数に入れる

Dockerイメージから、コンテナを起動すると、コンテナIDが付与されますが、このIDを変数に入れることで管理性が増します。具体的には、docker runの結果をコマンドラインのシェル変数に代入します。以下は、Dockerイメージ「centos:c66docker0001」から、コンテナを生成、起動し、起動したコンテナのコンテナIDをシェル変数ID0003に代入する例です。

# ID0003=$(docker run -d --name test0003 -i -t centos:c66docker0001 /bin/bash)
# echo $ID0003
f277d9902523cbdbebe3f7a048cf3621f3563f7bb3b60bc8ad23285dc98d1785

# docker ps -a
CONTAINER ID        IMAGE                  COMMAND     ...        STATUS        ... NAMES
f277d9902523        centos:c66docker0001   "/bin/bash" ...        Up 3 minutes  ... test0003

シェル変数にコンテナIDが格納されていますので、シェル変数に格納された値をコンテナIDとして、docker commitを行うことができます。

# docker commit $ID0003 centos:c66docker0003
c9801030b0b19c4fa2aeba450f407f385d6e2c0f1bca16a07ba7055fb32b16f2
#
日本ヒューレット・パッカード株式会社 プリセールス統括本部 ソリューションセンター OSS・Linux担当 シニアITスペシャリスト

兵庫県伊丹市出身。1996年頃からオープンソースに携わる。2000年よりUNIXサーバーのSE及びスーパーコンピューターの並列計算プログラミング講師を担当。科学技術計算サーバーのSI経験も持つ。2005年、大手製造業向けLinuxサーバー提案で日本HP社長賞受賞。2006年、米国HPからLinux技術の伝道師に与えられる「OpenSource and Linux Ambassador Hall of Fame」を2年連続受賞。日本HPプリセールスMVPを4度受賞。現在は、Linux、FreeBSD、Hadoop等のOSSを駆使したスケールアウト型サーバー基盤のプリセールスSE、技術検証、技術文書執筆を担当。日本HPのオープンソース・Linuxテクノロジーエバンジェリストとして講演活動も行っている。Red Hat Certified Engineer、Red Hat Certified Virtualization Administrator、Novell Certified Linux Professional、EXIN Cloud Computing Foundation Certificate、HP Accredited Systems Engineer Cloud Architect、Red Hat Certified System Administrator in Red Hat OpenStack、Cloudera Certified Administrator for Apache Hadoop認定技術者。HP公式ブログ執筆者。趣味はレーシングカートとビリヤード

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています