CMD與ENTRYPOINT的區別與聯繫

在Deckerfile中最容易混淆的兩個指令就是CMDENTRYPOINT,今天我們就來詳細分析這兩個指令具體是用來做什麼的。

一. 指令的定義
  • CMD指令的定義

下面我們來看官方給出的定義:

The main purpose of a CMD is to provide defaults for an executing container. 
These defaults can include an executable, or they can omit the executable, in
which case you must specify an ENTRYPOINT instruction as well.

CMD主要目的是爲執行中的容器提供默認值。這些默認值可以包含可執行文件,也可以省略可執行文件,在這種情下,您還必須指定一條ENTRYPOINT指令。

從上面的定義我可以看出分兩種情況,一種是給ENTRYPOINT指令提供默認的參數,一種是指定可執行文件,作爲容器啓動後執行的命令;
下面簡單看一下該指令的用法

CMD ["executable","param1","param2"] (exec模式, 這是推薦的方式)
CMD ["param1","param2"] (作爲 ENTRYPOINT 的默認參數)
CMD command param1 param2 (shell模式)

如果Dockerfile中包含多條CMD指令,則只有最後一條指令生效。

  • ENTRYPOINT指令的定義
An ENTRYPOINT allows you to configure a container that will run as an executable.

也就是說ENTRYPOINT纔是容器執行的入口,
下面介紹一下該指令的用法:

ENTRYPOINT ["executable", "param1", "param2"] (exec模式,推薦的方式)
ENTRYPOINT command param1 param2 (shell模式)
  • exec形式的ENTRYPOINT在執行命令docker run image時。命令行參數將附加在ENTRYPOINT指定的所有元素之後,並將覆蓋使用CMD指定的所有參數,這允許將參數傳遞到ENTRYPOINT,即docker run image -d-d參數傳遞給ENTRYPOINT。 您可以使用docker run --entrypoint覆蓋掉ENTRYPOINT指令。
  • shell形式的ENTRYPOINT可防止使用任何CMD或運行命令行帶入的參數,但其缺點是ENTRYPOINT將作爲/bin/sh -c的子命令啓動,該子命令不傳遞信號。因此您的可執行文件將不會從docker stop container接收到SIGTERM。
  • 如果Dockerfile中包含多條ENTRYPOINT指令,則只有最後一條指令生效。
    您可以使用ENTRYPOINT的exec形式來設置相當穩定的默認命令和參數,然後使用CMD來設置更可能被更改的其他默認值。

二. CMD和ENTRYPOINT如何相互作用
  • Dockerfile中應該至少指定CMDENTRYPOINT指令中的一種;

  • 當使用容器作爲可執行文件時應定義ENTRYPOINT

  • CMD應該被用作在容器中定義ENTRYPOINT命令或執行臨時命令默認參數。

  • 當使用其他參數運行容器時CMD 將被覆蓋

注意:如果CMD在基礎鏡像已有定義,則設置ENTRYPOINT會將CMD重置爲空值。在這種情況下,CMD必須在當前鏡像中重新定義一個值。


三. CMD和ENTRYPOINT的區別與聯繫
  • 相同點
    • 用法相似,都可以指定shell或exec函數調用的方式執行命令;
    • 當存在多個CMD指令或ENTRYPOINT指令時,只有最後一個生效;
  • 不同點
    • 容器啓動時,CMD指令指定的啓動命令可以被docker run指定的命令覆蓋,而ENTRYPOINT指令指定的啓動命令不能被覆蓋,而是將docker run指定的參數當做ENTRYPOINT指定命令的參數;
    • CMD指令可以作爲ENTRYPOINT指令的默認參數。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章