目錄
DockerFile
CMD
CMD指令在Dockerfile中僅允許一條,若出現多條,那麼都會被最後一條CMD 指令覆蓋掉
CMD指令主要是爲容器運行時提供默認值,這些默認值可以有執行命令操作,也可以只有參數配置,這需要與ENTRYPOINT結合使用
CMD指令有着三種配置形式
CMD ["executable","param1","param2"] 使用 exec 執行,推薦方式;
CMD command param1 param2 在 /bin/sh 中執行,提供給需要交互的應用;
CMD ["param1","param2"] 提供給 ENTRYPOINT 的默認參數;
CMD 示例:
CMD ["/usr/bin/wc","--help"]
CMD echo "This is a test." | wc -
ENTRYPOINT
ENTRYPOINT :配置容器啓動後執行的命令,並且不可被 docker run 提供的參數覆蓋。每個Dockerfile中只能有一個 ENTRYPOINT ,當指定多個時,只有最後一個起效
ENTRYPOINT指令配置形式
ENTRYPOINT ["executable", "param1", "param2"] (exec 形式, 推薦)
ENTRYPOINT command param1 param2 (shell 形式)
shell形式防止使用任何CMD或者運行命令行參數,但是缺點是ENTRYPOINT將作爲/bin/sh -c的子命令啓動,不傳遞信號。這意味着可執行文件將不是容器的PID 1,並且不接收Unix信號,因此您的可執行文件將不會從docker stop <container>接收到SIGTERM。
ENTRYPOINT 示例
ENTRYPOINT ["top", "-b"]
ENTRYPOINT exec top -b
CMD 與 ENTRYPOINT 優先級
- Dockerfile應該指定至少一個CMD或ENTRYPOINT命令。
- 在將容器用作可執行文件時,應該定義ENTRYPOINT。
- CMD應該用作定義ENTRYPOINT命令的默認參數或在容器中執行特別命令的方法。
- 當運行帶有可選參數的容器時,CMD將被覆蓋。
|
No ENTRYPOINT |
ENTRYPOINT exec_entry p1_entry (shell 形式) |
ENTRYPOINT [“exec_entry”, “p1_entry”] (exec 形式) |
NO CMD |
不允許 |
/bin/sh -c exec_entry p1_entry |
exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] (exec 形式) |
exec_cmd p1_cmd |
/bin/sh -c exec_entry p1_entry |
exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] (參數 形式) |
p1_cmd p2_cmd |
/bin/sh -c exec_entry p1_entry |
exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd (shell 形式) |
/bin/sh -c exec_cmd p1_cmd |
/bin/sh -c exec_entry p1_entr |
exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
CMD 與 ENTRYPOINT 使用建議:
(1)CMD命令用來執行image中的所有應用。CMD一般採用CMD [“executable”, “param1”, “param2”…]的格式來運行。所以,如果你的image是用來提供服務的,例如Apache,Rails。你就應該執行類似這樣的命令CMD ["apache2","-DFOREGROUND"]。
(2)在其他的case中,CMD用來執行特定的shell,比如:bash,python,perl等等。比如: CMD ["perl", "-de0"] , CMD ["python"] , or CMD [“php”, “-a”]。
(3)當你執行docker run -it python時就可以進入特定的shell中。
(4)CMD經常是配合 ENTRYPOINT 來使用的。除非確定你的用戶非常瞭解ENTRYPOINT 的特性。否則還是建議你事先設定好ENTRYPOINT
創建 Pod 時設置命令及入參
創建 Pod 時,可以爲其下的容器設置啓動時要執行的命令及其入參。如果要設置命令,就填寫在配置文件的 command
字段下,如果要設置命令的入參,就填寫在配置文件的 args
字段下。一旦 Pod 創建完成,該命令及其入參就無法再進行更改了。
- 如果在配置文件中設置了容器啓動時要執行的命令及其入參,那麼容器鏡像中自帶的命令與入參將會被覆蓋而不再執行。
- 如果配置文件中只是設置了入參,卻沒有設置其對應的命令,那麼容器鏡像中自帶的命令會使用該新入參作爲其執行時的入參。
通過 shell 來執行命令
有時候,您需要在 shell 腳本中運行命令。 例如,您要執行的命令可能由多個命令組合而成,或者它就是一個 shell 腳本。這時,就可以通過如下方式在 shell 中執行命令:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
Docker 與 Kubernetes 的對應關係
描述 | Docker 字段名稱 | Kubernetes 字段名稱 |
---|---|---|
容器執行的命令 | Entrypoint | command |
傳給命令的參數 | Cmd | args |
如果要覆蓋默認的 Entrypoint 與 Cmd,需要遵循如下規則:
如果在容器配置中沒有設置
command
或者args
,那麼將使用 Docker 鏡像自帶的命令及其入參。如果在容器配置中只設置了
command
但是沒有設置args
,那麼容器啓動時只會執行該命令,Docker 鏡像中自帶的命令及其入參會被忽略。如果在容器配置中只設置了
args
,那麼 Docker 鏡像中自帶的命令會使用該新入參作爲其執行時的入參。如果在容器配置中同時設置了
command
與args
,那麼 Docker 鏡像中自帶的命令及其入參會被忽略。容器啓動時只會執行配置中設置的命令,並使用配置中設置的入參作爲命令的入參。
下表涵蓋了各類設置場景:
鏡像 Entrypoint | 鏡像 Cmd | 容器 command | 容器 args | 命令執行 |
---|---|---|---|---|
[/ep-1] |
[foo bar] |
<not set> | <not set> | [ep-1 foo bar] |
[/ep-1] |
[foo bar] |
[/ep-2] |
<not set> | [ep-2] |
[/ep-1] |
[foo bar] |
<not set> | [zoo boo] |
[ep-1 zoo boo] |
[/ep-1] |
[foo bar] |
[/ep-2] |
[zoo boo] |
[ep-2 zoo boo] |
參考鏈接: