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