Dockerfileを使いこなす(1)

2015年10月6日(火)
古賀 政純

Dockerは、ハイパーバイザー側の仮想化ソフトに比べて、飛躍的にサーバー集約を実現できる特徴がありますが、それだけではありません。Dockerの醍醐味は、OSとアプリケーションをパッケージ化する手順を自動化できるという点にあります。では、OSとアプリケーションのパッケージ化を自動化するとは、一体どういうことなのでしょうか?そこには、今までのコンテナ型のソフトウェアにはない斬新な考えがあります。それが、Dockerfileです。今回と次回は、Dockerfileを使ったOSとアプリケーションのパッケージ化の具体的な自動化手順について解説します。

Dockerfileを使ったイメージの作成

Dockerイメージの作成や、イメージからコンテナを起動する一連の手順は、dockerコマンドでコマンドラインから入力することで可能ですが、コンテナとなるベースイメージの入手やコンテナへのアプリケーションのインストールなどの複数の作業を一括して行いたい場合があります。

Dockerでは、これらの複数の作業を一括で行うための仕組みが用意されており、これを実現するのが、Dockerfileです。Dockerfileは、開発環境におけるMakefileのように、Dockerで定義されている書式に従って記述し、それに基づいてアプリケーションのインストールなどを行い、Dockerイメージの作成を行います。Dockerfileにより、Dockerコンテナの一連のアプリケーション構築作業を自動化することができますが、それだけでなく、Dockerfileは、コンテナがどうようなアプリケーションで構成されているか、誰がメンテナーなのか、どういう手順で構築されているのかなどの重要な情報を含んでおり、コンテナのメンテナンス効率の向上に大きく貢献します。

以下では、CentOS 7で稼働するApache Webサーバーが起動するコンテナのイメージファイルの作成を例に、Dockerfileを解説します。まず、アプリケーションであるApacheが稼働するコンテナのためのDockerfileを記述します。Dockerfileを配置する場所は、任意ですが、今回は、/root/apacheディレクトリを作成し、その下にDockerfileを作成することにします。

# mkdir /root/apache
# cd /root/apache
# vi Dockerfile
FROM            centos:centos7.1.1503   (1)
MAINTAINER      Masazumi Koga (2)
ENV             container docker (3)
RUN             yum update  -y && yum clean all (4)
RUN             yum swap -y fakesystemd systemd && yum clean all (5)
RUN             yum install -y httpd && yum clean all (6)
RUN             echo "Hello Apache." > /var/www/html/index.html (7)
RUN             systemctl enable httpd (8)
EXPOSE          80 (9)
  1. 使用するDockerイメージ名を指定
  2. Dockerfileのメンテナーを記述
  3. 環境変数を設定
  4. パッケージのアップデート
  5. systemdをDockerイメージにインストール
  6. httpdパッケージをDockerイメージにインストール
  7. テスト用のHTMLファイルを配置
  8. コンテナ起動時にhttpdサービスが起動するように設定
  9. Dockerコンテナが外部に開放するポート番号を指定

Dockerfile内では、FROM行に利用するイメージの種類を記述します。イメージ名はコマンドラインから「docker images」で確認可能ですので、一覧に表示されているイメージ名を記述します。ここではCentOS 7.1のイメージ「ceentos:centos7.1.1503」を指定しています。

RUN行では、Dockerのイメージの作成時に実行するコマンドを記述します。今回、RUN行に、「yum swap -y fakesystemd systemd」が指定されています。Dockerリポジトリに標準で用意されているCentOS 7.1のDockerイメージは、デフォルトでsystemdを利用しないものが用意されています。しかし、多くのCentOS 7.1向けのアプリケーションやサービスがsystemdを使用するため、Dockerイメージにsystemdをインストールしたい場合があります。今回は、yumコマンドで、fakesystemdを削除し、systemdをインストールしています。さらに、RUN行の「yum install -y httpd」は、Apache Webサーバーのhttpdパッケージをインストールする記述です。今回使用するDockerイメージは、CentOS 7.1のsystemdを有効にしますので、RUN行で「systemctl enable httpd」を記述し、コンテナが起動した際に、自動的にApache Webサーバーが起動するようにします。Apache Webサーバーのコンテナが外部に開放するポート番号をEXPOSE行で指定します。Dockerfileを記述したら、docker buildにより、Dockerイメージを生成します。

# pwd
/root/apache

# ls -l
合計 4
-rw-r--r--. 1 root root 328  6月 11 11:32 Dockerfile

# docker build  -f ./Dockerfile -t centos:c71apache01 --no-cache=true .

Apache Webサーバー入りのDockerイメージ「c71apache01」が作成されているかを確認します。

[root@ml115g5 apache]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              c71apache01         89a496bc9082        38 seconds ago      384.2 MB
docker.io/centos    centos7.1.1503      f1dade627e25        7 weeks ago         212.1 MB

作成したDockerイメージ「c71_apache01」を使ってDockerコンテナを起動します。今回起動するコンテナ名は、「web0001」としました。

# docker run -d --privileged --name web0001 -i -t -p 80:80 centos:c71apache01 /sbin/init
cdb3c5da9d4e4f2d9c2bb2698234531a059384a160e8ff43c4a75591495a4ea4\

CentOS 7.1ベースのDockerイメージにおいて、コンテナ内でsystemdを使用する場合は、コンテナの起動オプションに、「--privileged」オプション、または、「--cap-add=SYS_ADMIN」オプションが必要になります。またコンテナの起動に指定するコマンドは、「/sbin/init」を指定します。コンテナが起動しているかどうかを確認します。

# docker ps -a
CONTAINER ID IMAGE                COMMAND      ... STATUS        PORTS                NAMES
cdb3c5da9d4e centos:c71apache01   "/sbin/init" ... Up 44 seconds 0.0.0.0:80->80/tcp   web0001

コンテナ「web0001」が起動していることがわかります。ホストOSからコンテナ「web0001」にログインします。バックグランドで起動しているコンテナへのログインは、docker execで行います。docker execでは、現在稼働しているコンテナ名(ここではweb0001)を指定します。今回は、稼動中のコンテナにログインして、コマンドプロンプトからコマンドラインによる入力作業を行うため、/bin/bashを指定します。

# docker exec -i -t web0001 /bin/bash
[root@cdb3c5da9d4e /]#

プロンプトが変化し、コンテナにログインできていますので、コンテナ上でApache Webサービスが起動しているかを確認します。

[root@cdb3c5da9d4e /]# systemctl status httpd |grep active
   Active:active (running) since Thu 2015-06-11 02:52:07 UTC; 3min 29s ago

コンテナがhttpdサービスを正常に起動できていることを確認できたら、コンテナに割り振られたIPアドレスをコンテナ上で確認します。以下では、コンテナweb0001に、IPアドレス172.17.0.26/16が割り振られていることがわかります。

[root@cdb3c5da9d4e /]# ip a |grep inet
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
    inet 172.17.0.26/16 scope global eth0
    inet6 fe80::42:acff:fe11:1a/64 scope link

コンテナが外部にWebサービスを提供できているかをホストマシンから確認します。コマンドラインから確認するには、curlコマンドが有用です。

# curl http://172.17.0.26/index.html
Hello Apache.
#

[補足]

稼働中のコンテナのbashプロンプトを起動せずに、ホストOSから直接、コンテナ内のコマンドを実行することも可能です。例えば、ホストOSから、上記のweb0001コンテナにインストールされているipコマンドを使ってweb0001コンテナのIPアドレスを調べる場合は、以下のようにdocker execで直接ipコマンドを指定することができます。

# docker exec -i -t web0001 ip a
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
    inet 172.17.0.26/16 scope global eth0
    inet6 fe80::42:acff:fe11:1a/64 scope link
日本ヒューレット・パッカード株式会社 プリセールス統括本部 ソリューションセンター 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メルマガ会員のサービス内容を見る

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