連載
» 2014年07月08日 18時00分 UPDATE

いまさら聞けないDocker入門(3):Dockerfileとdocker buildコマンドでDockerイメージの作成 (2/2)

[大瀧隆太,クラスメソッド株式会社]
前のページへ 1|2       

ENTRYPOINTとCMDの使い分け

 「docker run」コマンドでは、引数にコンテナーで実行するコマンドを指定しました。Dockerイメージの用途によっては、サービスを提供する場合など実行するコマンドが最初から決まっている場合があります。

 「ENTRYPOINT」および「CMD」を記述することで実行するコマンドおよび引数を事前に定義でき、「docker run」コマンド実行時に省略できるようになります。「CMD」の場合は「docker run」で実行するコマンドを上書きできますが、「ENTRYPOINT」の場合は上書きできない点が異なります。

 「ENTRYPOINT」でnginxの実行を追加し、Dockerイメージをタグ「1.1」で再作成します。

~/nginx1$ vim Dockerfile         # ENTRYPOINT行を末尾に追加
FROM ubuntu
MAINTAINER takipone <xxxx@gmail.com>
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/
ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
~/nginx1$ docker build -t takipone/nginx:1.1 .
Uploading context 3.584 kB
Uploading context
Step 0 : FROM ubuntu
 ---> ef83896b7fb9
Step 1 : MAINTAINER takipone <xxxx@gmail.com>
 ---> Using cache
 ---> aebe4cba91dc
Step 2 : RUN apt-get install -y nginx
 ---> Using cache
 ---> 0e34b5b004a7
Step 3 : ADD index.html /usr/share/nginx/html/
 ---> Using cache
 ---> fb37319fbfc5
Step 4 : ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
 ---> Running in 80a13fce2cf7
 ---> 03d14086a075
Successfully built 03d14086a075
Removing intermediate container 80a13fce2cf7
~/nginx1$

 実行結果の中に「Using cache」という行が含まれていることが分かると思います(13・16・19行目)。「docker build」コマンドは、別のイメージ作成時のローカルキャッシュを使い回す性質があり、イメージ作成時間が短縮されるようになっています。

 それでは、実行コマンドを省略してDockerイメージ「takipone/nginx:1.1」からコンテナー「nginx2」を作成してみます。

~/nginx1$ docker run -d --name nginx2 -p 80:80 takipone/nginx:1.1
476110c7380f193b89dfb9f05bb525190826ae238a8ced97d6dad46a44212ed2
~/nginx1$ docker ps
CONTAINER ID        IMAGE                COMMAND                CREATED         STATUS              PORTS                NAMES
476110c7380f        takipone/nginx:1.1   /bin/sh -c /usr/sbin   2 seconds ago       Up 1 seconds        0.0.0.0:80->80/tcp   nginx2
~/nginx1$ curl localhost
Hello!
~/nginx1$

 ちゃんとnginxが動作していますね。確認できたら、コンテナーを削除しておきましょう。

~/nginx1$ docker stop nginx2
nginx1
~/nginx1$ docker rm nginx2
nginx1
~/nginx1$ 

Tips「カレントディレクトリと環境変数」

 「docker build」では「Dockerfile」の1行ごとにシェルが起動してDockerイメージに操作を行うため、カレントディレクトリや環境変数の変更が引き継がれません。カレントディレクトリは「Dockerfile」の「WORKDIR」、環境変数は「ENV」で指定しましょう。


Tips「nsenterによるDockerコンテナーのデバッグ」

 作成したDockerイメージがきちんと構成されているかは、そのイメージから再度Dockerコンテナーを起動して確認することになります。コンテナーで実行しているサービスなどにアクセスして動作を確認するのはもちろんですが、コンテナー内のファイルの内容やコンテナー内でコマンドを実行して構成をデバッグしたいこともあるでしょう。

 そんなときに便利なツールとして「nsenter」があります。「nsenter」は、Linux Namespace上でプロセスを起動するユーティリティコマンドです。起動中のDockerコンテナー上でシェルを起動し、コマンド操作を行えます。

 「util-linux」パッケージのバージョン2.23で追加された新しいユーティリティのため2014/07/02現在、Ubuntu 14.04のaptリポジトリには含まれていません。ソースからインストールすることも可能ですが、手軽にインストールする方法として、Dockerコンテナーの「jpetazzo/nsenter」を実行する方法があります。

$ docker run -v /usr/local/bin:/target jpetazzo/nsenter
Unable to find image 'jpetazzo/nsenter' locally
Pulling repository jpetazzo/nsenter
bc97403a3d6e: Download complete
:
c2f321a80e65: Download complete
Installing nsenter to /target
Installing docker-enter to /target
$

 これにより、「/usr/local/bin/nsenter」が作成されます。

 「nsenter」コマンドでは、DockerコンテナーのプロセスID(Pid)を指定します。DockerコンテナーのプロセスIDは、コンテナーの詳細情報を出力する「docker inspect」コマンドの結果に含まれます。

$ docker ps                     # DockerコンテナーのCONTAINER IDを確認
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
1e5494135774        ubuntu:latest       /bin/bash           2 hours ago         Up 2 hours                              ubuntu1
$ docker inspect 1e5494135774   # Dockerコンテナーの詳細情報を確認
[{
    "ID": "1e549413577461a60ef4e9794305ce0cdba18d3f9966294987d526c4d240e15c",
    "Created": "2014-07-02T04:01:48.744524496Z",
    "Path": "/bin/bash",
    "Args": [],
    "Config": {
        "Hostname": "1e5494135774",
        :
    },
    "State": {
        "Running": true,
        "Pid": 2382,
        "ExitCode": 0,
        "StartedAt": "2014-07-02T04:01:48.813153579Z",
        "FinishedAt": "0001-01-01T00:00:00Z",
        "Ghost": false
    },
    :
}]
$ docker inspect 1e5494135774 | grep Pid
        "Pid": 2382,
$

 プロセスIDが分かったので、「nsenter」コマンドにDockerコンテナーで実行するための適切なオプションとプロセスIDを引数に指定し、実行します。

$ sudo nsenter --mount --uts --ipc --net --pid --target 2382
root@1e5494135774:/# ps
  PID TTY          TIME CMD
  485 ?        00:00:00 bash
  488 ?        00:00:00 ps
root@1e5494135774:/#

 コンテナー内でシェルが起動しました。


次回はDockerイメージを公開する「Docker Hub」について

 Dockerイメージを作成する方法として、「Dockerfile」と「docker build」の使い方を紹介しました。「Dockerfile」は、GitHubなどで多数公開されているものがありますので、既存の「Dockerfile」を参考にしつつ、好みのDockerイメージ作成に役立てましょう。

 次回は、作成したDockerイメージを公開する、Docker Hubの利用について解説します! ご期待ください。

著者プロフィール

大瀧隆太

大瀧隆太

所属/職種:クラスメソッド株式会社 シニアソリューションアーキテクト

ビール片手に邦楽ロックバンドのライブ/フェスへの参加をこよなく愛する。業務ではAWS導入支援やAWS研修の講師に携わる一方、自動化/デプロイツールの活用でクラウドエンジニアがどこまでスケールできるのか日々試行錯誤している。

ブログURL:http://dev.classmethod.jp/


前のページへ 1|2       

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。