[Docker]CMDとENTORYPOINTの挙動の違い


はじめに

Docker初心者です。自分用に記載。
今回、Dockerfileに記述する命令、CMDENTRYPOINTに関する記事を投稿してみました。

Dockerとは

Dockerはコンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンソースソフトウェアあるいはオープンプラットフォームである。

Dockerはコンテナ仮想化を用いたOSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする。かつその環境自体をアプリケーションと同じようにコード(イメージ)として管理可能にする。Dockerを開発・テスト・デプロイに用いることで「コードを書く」と「コードが製品として実行される」間の時間的ギャップを大きく短縮できる。
(Wikipediaより)

つまりdockerを使うメリットは、

  • 起動・実行にかかる処理の負荷(オーバヘッド)が少ないため、高速
  • 環境をコード化(イメージ化)することで、そのコードをもとに誰でも同じ環境を作ることができる。
  • 環境の設定を変更したとき、再構築の時間が短くて済む。また、システムの廃棄も容易。

Dockerfileとは

Dockerイメージを作るやつ。

わからなかったこと

CMDENTRYPOINTもどちらもコンテナ起動時に実行するコマンドなのははわかったが、
docker run実行時に、どう挙動が違うのか?

CMDとENTRYPOINTの挙動の違い

これらの記事を参考にしました。
http://docs.docker.jp/engine/reference/builder.html#cmd-entrypoint
https://gist.github.com/goldeneggg/e2b2d7ca9ea2e649df5f

docker run の際、コマンド引数指定ありの時に挙動の違いがありました。
また、ENTORYPOINTのみ、シェルを介す書き方と、介さない書き方にも違いがあることもわかりました。

CMD ls(シェルを介す) CMD ls -l(オプションあり) CMD ["ls", "-l"](シェルを介さない) ENTRYPOINT ls(シェルを介す) ENTRYPOINT ls -l(オプションあり) ENTRYPOINT ["ls", "-l"](シェルを介さない)
docker run の際、コマンド引数指定なし CMDで指定したコマンドを実行するだけ CMDで指定したコマンドを実行するだけ CMDで指定したコマンドを実行するだけ ENTRYPOINTで指定したコマンドを実行するだけ ENTRYPOINTで指定したコマンドを実行するだけ ENTRYPOINTで指定したコマンドを実行するだけ
docker run の際、コマンド引数指定あり 引数で指定したコマンドが実行される 引数で指定したコマンド(とオプション)が実行される 引数で指定したコマンド(とオプション)が実行される ENTRYPOINTで指定したコマンドがそのまま実行される ENTRYPOINTで指定したコマンドがそのまま実行される エラーになる (引数で指定したコマンドがオプション扱いになるため)

CMDの場合

  • 上の表を見てわかる通り、シェルを介す場合でも介さない場合でもdocker runの際、コマンド引数を指定してあると、CMDで書いたものは無視されます。(公式で言うと、上書きされます。)

ENTRYPOINTの場合

  • シェルを介す場合
    • docker runの際、コマンド引数を指定してあげても、Dockerfileに書いたENTRYPOINTで指定したコマンドがそのまま実行されます。引数の方は無視されます。
  • シェルを介さない場合
    • docker runの際、コマンド引数を指定してあげてしまうと、エラーになります。これがちょっとややこしい。実際例を見てもらったほうが分かりやすいと思います。
Dockerfile

FROM centos
MAINTAINER hoge

ENTRYPOINT ["ls", "-l"]

% docker run --rm IMAGE_ID ls -lh
ls: cannot access ls: No such file or directory
:

このように、ENTRYPOINTのparam部分 -lが コマンド引数 ls で上書きされます。
つまり、paramの部分だけ上書きされます。

であれば、docker runの際、lsコマンドの引数としてオプションを指定したらどうなるのでしょうか?
結果

% docker run --rm IMAGE_ID -lh
dr-xr-xr-x  2 root root 4.0K Apr 12 01:10 bin
drwxr-xr-x  4 root root  80K May  2 07:57 dev
drwxr-xr-x 40 root root 4.0K May  2 07:57 etc
drwxr-xr-x  2 root root 4.0K Sep 23  2011 home
:

エラーを吐かず、オプションとして認識されました。