在Deckerfile中最容易混淆的兩個指令就是
CMD
與ENTRYPOINT
,今天我們就來詳細分析這兩個指令具體是用來做什麼的。
一. 指令的定義
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中應該至少指定
CMD
或ENTRYPOINT
指令中的一種; -
當使用容器作爲可執行文件時應定義
ENTRYPOINT
; -
CMD
應該被用作在容器中定義ENTRYPOINT
命令或執行臨時命令默認參數。 -
當使用其他參數運行容器時
CMD
將被覆蓋
注意
:如果CMD
在基礎鏡像已有定義,則設置ENTRYPOINT
會將CMD
重置爲空值。在這種情況下,CMD
必須在當前鏡像中重新定義一個值。
三. CMD和ENTRYPOINT的區別與聯繫
- 相同點
- 用法相似,都可以指定shell或exec函數調用的方式執行命令;
- 當存在多個
CMD
指令或ENTRYPOINT
指令時,只有最後一個生效;
- 不同點
- 容器啓動時,
CMD
指令指定的啓動命令可以被docker run
指定的命令覆蓋,而ENTRYPOINT
指令指定的啓動命令不能被覆蓋,而是將docker run
指定的參數當做ENTRYPOINT
指定命令的參數; CMD
指令可以作爲ENTRYPOINT
指令的默認參數。
- 容器啓動時,