ポイント: DockerのCMDおよびENTRYPOINTは、コンテナが起動時にコマンドを実行する方法を決定するDockerfile内の重要な命令です。CMDはオーバーライド可能なデフォルトコマンドを設定し、ENTRYPOINTコマンドは無条件に実行されます。
- CMDはコマンドライン引数を介してオーバーライドできるが、ENTRYPOINTはできない。
- デフォルトにはCMDを使用し、常に実行する必要がある重要なコマンドにはENTRYPOINTを使用します。
CMDとENTRYPOINTは、コンテナが起動するときに実行されるコマンドを定義するための2つのDockerfile命令です。これらの命令をDockerfileで使用する必要がありますので、ユーザーはイメージと簡単に対話できます。CMDとENTRYPOINTは一緒に動作するため、しばしば理解するのが混乱することがあります。この記事は、この領域での潜在的な不一致を解消するのに役立ちます。
クラウドネイティブの設定では、Docker コンテナは、アプリケーションがさまざまなコンピューティング環境で効果的に実行されることを保証する重要な要素です。これらのコンテナは、アプリケーションのワークフローの特定のタスクとプロセスを運ぶことを意図しており、Dockerイメージによってサポートされています。
一方、イメージはDockerfileを通じてDocker命令を実行することによって実行されます。Dockerfileをビルドして実行するために使用する命令(コマンド)は3つのタイプがあります:
- RUN. 主にイメージをビルドし、アプリケーションやパッケージをインストールするために使用され、RUNは結果をコミットすることによって既存のイメージの上に新しいレイヤーを構築します。
- CMD. コンテナが実行中のときにDockerコマンドラインインターフェース(CLI)からオーバーライド可能なデフォルトパラメータを設定します。
- ENTRYPOINT. CLIパラメータで実行されるときにオーバーライドできないデフォルトパラメータ。
任意のDockerイメージは、コンテナを開始するためにENTRYPOINTまたはCMDの宣言を持つ必要があります。ENTRYPOINTとCMDの命令は、一見似ているように見えますが、コンテナイメージを構築する方法には根本的な違いがあります。
(
シェル形式と実行可能形式
最初に、Dockerデーモンが指示を処理する方法を理解する必要があります。
すべてのDocker命令タイプ(コマンド)は、シェル形式または実行可能形式のいずれかで指定できます。これらの2つのコマンドを理解するために、サンプルのDockerfileをビルドしましょう。
(詳細を探る Dockerコマンド.)
シェルコマンド形式
名前が示すように、命令のシェル形式は、シェル内で実行されるプロセスを開始します。これを実行するには、/bin/sh -c <command>を呼び出します。
通常、シェルコマンドによるすべての実行は、結果を返す前に環境変数を検証する必要があります。
シェルコマンドの構文は、次の形式で指定されます:
<instruction> <command>
シェル形式のコマンドの例は以下の通りです:
RUN yum -y update
RUN yum -y install httpd
COPY ./index.html/var/www/index.html
CMD echo “Hello World”
シェルコマンドを使用するDockerfileという名前のDarwinは、以下の仕様を持ちます:
ENV name Darwin
ENTRYPOINT /bin/echo "Welcome, $name"
(上記で使用されるコマンド仕様は参考用です。必要に応じて他のシェルコマンドを含めることができます。)
上記の仕様に基づくdocker run-it Darwinコマンドの出力は:
ようこそ、Darwin
このコマンド形式は、シェルに検証を通過させて結果を返すように指示します。これにより、パフォーマンスのボトルネックが生じることがよくあります。そのため、シェル形式は、特定のコマンド/環境検証の要件がない限り、通常は好まれない方法です。
実行可能コマンド形式
シェルコマンドタイプとは異なり、実行可能形式で書かれた命令は、シェル検証と処理を経ることなく、実行可能バイナリを直接実行します。
実行可能コマンドの構文は、次の形式で指定されます:
<instruction> ["実行可能","パラメータ1","パラメータ2", …]
実行可能コマンドの例は以下の通りです:
RUN ["yum", "-y", "update"]
CMD ["yum", "-y" "install" "httpd"]
COPY ["./index.html/var/www/index.html"]
実行可能形式でDarwinという名前のDockerfileをビルドするには:
ENV name Darwin
ENTRYPOINT ["/bin/echo", "Welcome, $name"]
これによりシェル処理が回避されるため、docker run -it Darwinコマンドの出力は、ようこそ、$nameとなります。
これは、Dockerfile内で環境変数が置き換えられないためです。exec形式でbashを実行するには、/bin/bashを実行可能として指定します。すなわち:
ENV name Darwin
ENTRYPOINT ["/bin/bash", “-c” "echo Welcome, $name"]
これによりシェル処理が促され、Dockerfileの出力は: ようこそ、Darwinとなります。
コンテナ化されたセットアップのコマンドは、望ましい出力のためにオペレーティング環境に渡される重要な命令です。指示を渡す際に正しいコマンド形式を使用することが最も重要です。
- 望ましい結果を返す
- 環境を不必要な処理に押し込むことがないようにし、運用効率に影響を与えない
エンタープライズDevOpsに興味がありますか? BMCのDevOpsソリューションとツールについて詳しく学びましょう。 ›
CMD vs. ENTRYPOINT: 基本的な違い
CMDとENTRYPOINT命令には、機能における基本的な違いがあり、それぞれが異なるアプリケーション、環境、およびシナリオに適しています。
両者は、コンテナが実行を開始する際に実行されるプログラムを指定しますが:
- CMDコマンドは、docker runコマンド内にパラメータが記載されている場合、デーモンによって無視されます。
- ENTRYPOINT命令は無視されず、代わりにコマンドの引数としてそれらを扱ってコマンドラインパラメータとして追加されます。
次に、詳しく見てみましょう。Dockerコンテナを実行するさまざまなステージを通過するために、両方のコマンド形式を使用します。
Docker CMD
Docker CMDコマンドは、以下で構成されるDockerfileを介して渡されます:
- Dockerイメージをビルドするための命令
- イメージ上でコンテナを実行するためのデフォルトのバイナリ
CMD命令タイプでは、CLIにコマンドが指定されていなくてもデフォルトのコマンド/プログラムが実行されます。
理想的には、Dockerfile内には単一のCMDコマンドがあるべきです。たとえば、Dockerfileに複数のCMDコマンドがある場合、最後の1つを除いてすべてが実行のために無視されます。
CMDコマンドの重要な特徴は、オーバーライドできる能力です。これにより、ユーザーはCLIを介してコマンドを実行してDockerfile内のCMD命令をオーバーライドすることができます。
Docker CMD命令は、シェル形式とExec形式の両方で書くことができます:
- Exec形式: CMD ["実行可能","パラメータ1","パラメータ2"]
- シェル形式: CMD コマンド パラメータ1 パラメータ2
ステージ1. Dockerfileの作成
Dockerfileをビルドする際、CMD命令はコンテナが実行されるときに実行されるデフォルトのプログラムを指定します。ひとつのポイントとして、CMDコマンドはコマンドライン引数が欠けているときにのみ利用されます。
CMD命令を持つDockerfileという名前のDarwinを見て、その動作を分析します。
DarwinのDockerfile仕様は:
ステージ1. Dockerfileの作成
FROM centos:7
RUN apt-get update
RUN apt-get -y install python
COPY ./opt/source code
CMD ["echo", "Hello, Darwin"]
上記のファイルのCMD命令は、CLI引数なしでコンテナが起動されるときにHello, Darwinというメッセージをエコーします。
ステージ2. イメージのビルド
Dockerイメージは、次のコマンドを使用してDockerfileからビルドされます:
ステージ2. イメージのビルド
$ docker build -t Darwin .
上記のコマンドは次の2つのことを行います:
- Dockerデーモンにイメージをビルドするよう指示します
- 現在のディレクトリ内にあるDarwinというタグ名を設定します
ステージ3. Dockerコンテナの実行
Dockerコンテナを実行するには、docker runコマンドを使用します:
ステージ3. Dockerコンテナの実行
$ docker run Darwin
これによりコマンドライン引数が除外されるため、コンテナはデフォルトのCMD命令を実行し、Hello, Darwinという出力を表示します。
runコマンドで引数を追加すると、デフォルトの命令がオーバーライドされます。すなわち:
$ docker run Darwin hostname
CMDデフォルトコマンドがオーバーライドされるため、上記のコマンドはコンテナを実行し、ホスト名を表示します。このため、Dockerfile内のエコー命令は無視され、次の出力が返されます:
6e14beead430
これはDarwinコンテナのホスト名です。
CMDを使用する時
CMD命令を使用する最良の方法は、ユーザーがコマンドラインで引数を入力しないときに実行されるデフォルトプログラムを指定することです。
この命令は、コンテナイメージが実行されるとすぐにアプリケーションを開始することによって、コンテナを実行状態に保ちます。これにより、CMD引数はコンテナが起動するとすぐにベースイメージを読み込みます。
さらに、特定の使用例では、docker runコマンドをCLIを介して実行して、Dockerfile内で指定された命令をオーバーライドできます。
Docker ENTRYPOINT
Dockerfileでは、ENTRYPOINT命令はコンテナが初期化されるときに常に実行される実行可能ファイルを設定するために使用されます。
CMDコマンドとは異なり、ENTRYPOINTコマンドは無視されたりオーバーライドされたりすることはありません。コンテナがコマンドライン引数を指定して実行される場合でも同様です。
Docker ENTRYPOINT命令は、シェル形式とexec形式の両方で書かれることがあります:
- Exec形式: ENTRYPOINT ["実行可能","パラメータ1","パラメータ2"]
- シェル形式: ENTRYPOINT コマンド パラメータ1 パラメータ2
ENTRYPOINT命令は、特定のコマンドを実行するためのDockerfileを構築するために使用されます。
これらは、Entrypointコマンドを持つDockerfile仕様の参考です:
FROM centos:7
RUN apt-get update
RUN apt-get -y install python
COPY ./opt/source code
ENTRYPOINT ["echo", "Hello, Darwin"]
上記のDockerfileは、コンテナが実行されるときにHello, DarwinをエコーするENTRYPOINT命令を使用しています。
次のステップはDockerイメージをビルドすることです。コマンドを使用します:
$ docker build -t Darwin .
このイメージをビルドするとき、デーモンはENTRYPOINT命令を探し、コマンドライン入力があろうとなかろうと実行されるデフォルトプログラムとして指定します。
コマンドライン引数なしでDarwinイメージを使用してDockerコンテナを実行すると、デフォルトのENTRYPOINT命令が実行され、Hello, Darwinをエコーします。
CLIを介して追加のコマンドライン引数が導入された場合、ENTRYPOINTは無視されません。代わりに、コマンドラインパラメータはENTRYPOINTコマンドの引数として追加されます。すなわち:
$ docker run Darwin hostname
ENTRYPOINTを実行し、Hello, Darwinをエコーし、その後ホスト名を表示して次の出力を返します:
Hello, Darwin 6e14beead430
ENTRYPOINTを使用する時
ENTRYPOINT命令は、コンテナが起動するときに常に特定のコマンドを実行する必要がある単一目的およびマルチモードのイメージに適しています。
CMDとENTRYPOINT命令を一緒に使用する
操作における根本的な違いがある一方で、CMDとENTRYPOINT命令は相互排他的ではありません。Dockerfileでの命令を組み合わせて使用する必要があるシナリオがいくつかあります。
それらをブレンドする非常に人気のある使用例は、コンテナの起動タスクを自動化することです。この場合、ENTRYPOINT命令は実行可能ファイルを定義するために使用され、CMDはパラメータを定義するために使用されます。
Darwin Dockerfileを以下の仕様で確認しましょう:
FROM centos:7
RUN apt-get update
RUN apt-get -y install python
COPY ./opt/source code
ENTRYPOINT ["echo", "Hello"]CMD [“Darwin”]
その後、コマンドを使用してイメージがビルドされます:
$ docker build -t darwin .
CLIパラメータなしでコンテナを実行すると、Hello, Darwinというメッセージをエコーします。
Usernameのようなパラメータを追加すると、CMD命令がオーバーライドされ、CLIパラメータを引数として使用してENTRYPOINT命令のみが実行されます。たとえば、コマンドは:
$ docker run Darwin User_JDArwin
出力を返します:
Hello User_JDArwin
これはENTRYPOINT命令が無視されることができず、CMDの場合はコマンドライン引数が命令をオーバーライドするためです。
ENTRYPOINTまたはCMDを使用する
ENTRYPOINTとCMDは、Dockerfileを構築し実行するために不可欠ですが、それは単に使用ケースに依存します。一般的な指針として:
- 実行可能なDockerイメージを構築する際には、常に実行する必要があるコマンドを使用するためにENTRYPOINT命令を使用します。
- Dockerコンテナが実行される際に明示的なコマンドライン使用があるまでデフォルトの命令として機能する引数の追加セットが必要な場合はCMD命令を使用します。
コンテナイメージは、アプリケーションを実行するために必要なランタイム命令、システムツール、およびライブラリを含む必要があります。Dockerセットアップから最高の結果を得るためには、管理者がこれらの命令のさまざまな機能、構造、およびアプリケーションを理解することが強く推奨されます。これらは、イメージを構築し、コンテナを効率的に実行するのに役立つ重要な機能です。
関連する読み物
Docker ガイド
これらの投稿は私自身のものであり、BMCの立場、戦略、または意見を必ずしも表すものではありません。