docker entrypoint和cmd,Dockerfile 中的 CMD 和 ENTRYPOINT 有什么區別

 2023-11-18 阅读 26 评论 0

摘要:推薦閱讀 Helm3(K8S 資源對象管理工具)視頻教程:https://edu.csdn.net/course/detail/32506 Helm3(K8S 資源對象管理工具)博客專欄:https://blog.csdn.net/xzk9381/category_10895812.html 本文原文鏈接:https://blog.csdn

推薦閱讀

Helm3(K8S 資源對象管理工具)視頻教程:https://edu.csdn.net/course/detail/32506
Helm3(K8S 資源對象管理工具)博客專欄:https://blog.csdn.net/xzk9381/category_10895812.html

本文原文鏈接:https://blog.csdn.net/xzk9381/article/details/114635083,轉載請注明出處。如有發現文章中的任何問題,歡迎評論區留言。

在編寫 Dockerfile 過程中,需要使用 CMD 或 ENTRYPOINT 來指定容器運行時的命令。單從功能上來看,這兩個命令的功能幾乎是重復的,一般情況下使用其中一個命令就可以滿足大部分的需求。接下來說一下 CMD 和 ENTRYPOINT 的不同點。

一、exec 和 shell 模式

首先要明確的一點就是 CMD 和 ENTRYPOINT 指令都可以使用 exec 和 shell 模式。這兩種模式主要是用來指定容器中的不同進程作為 1 號進程。

1. exec 模式

docker entrypoint和cmd,前面提到了,exec 和 shell 模式會指定不同的進程作為容器內的 1 號進程。使用 exec 模式時,Dockerfile 中指定的命令就是容器內的 1 號進程,例如:

FROM ubuntu
CMD ["top"]

使用該 Dockerfile 構建鏡像并運行,進入到容器內部使用 ps 命令可以發現 1 號進程就是 top 命令。

由于 exec 模式不會通過 shell 執行指令,所以使用該模式時無法獲取到環境變量:

FROM ubuntu
CMD ["echo","${HOSTNAME}"]

構建鏡像并運行后,可以發現在日志輸出中的內容還是 ${HOSTNAME},并沒有轉換為對應的值。

docker run cmd,但是如果使用 exec 模式執行 shell 就可以獲得環境變量了:

FROM ubuntu
CMD ["/bin/bash","-c","echo ${HOSTNAME}"]

需要注意的是,使用 exec 模式需要使用雙引號將參數包裹。

2. shell 模式

使用 shell 模式時,docker 會以 /bin/sh -c “task command” 的方式執行任務命令。也就是說容器中的 1 號進程不是任務進程而是 bash 進程:

FROM ubuntu
CMD top

構建鏡像并運行后,使用 ps 命令可以發現 1 號進程是 /bin/sh -c top。

二、CMD 命令

docker cmd、CMD 命令用于為容器提供默認的啟動命令。該命令有三種使用方式,其中最常用的一種是為 ENTRYPOINT 提供默認的參數,另外兩種則是上面提到的 shell 和 exec 模式:

CMD ['param1','param2']

需要注意的是,在使用 docker run 命令時,如果手動指定了啟動的命令,那么該命令會覆蓋 Dockerfile 中的 CMD 指令。而且通過命令行指定的參數并不會傳遞到 CMD 命令中。

三、ENTRYPOINT 命令

ENTRYPOINT 命令同樣用于為容器提供默認的啟動命令。該命令有兩種使用方式,也就是前面提到的 shell 模式和 exec 模式。基本用法是和 CMD 命令一樣的,但是它也包含了一些特殊用法。

1. 示例一:指定 ENTRYPOINT 使用 exec 模式時,命令行上指定的參數會作為添加到 ENTRYPOINT 指定命令的參數列表中

FROM ubuntu
ENTRYPOINT ["top","-b"]

制作鏡像后,使用如下命令啟動容器:

docker run --rm test:v1 -c

dockerfile workdir。進入容器中查看 1 號進程,可以發現進程為 top -b -c,這就說明命令行中的參數被添加到參數列表中了。

2. 示例二:使用 CMD 命令指定默認的參數列表

FROM ubuntu
ENTRYPOINT ["top","-b"]
CMD ["-c"]

制作鏡像后,使用如下命令啟動容器(不帶有命令行參數):

docker run --rm test:v1

進入容器中查看 1 號進程,可以發現進程為 top -b -c。如果在啟動容器時指定了參數:

docker run --rm test:v1 -n 1

那么 -n 1 參數會覆蓋 CMD 中的參數,容器中實際執行的命令為 top -b -n 1

3. 示例三:指定 ENTRYPOINT 使用 shell 模式時,會完全忽略命令行參數

FROM ubuntu
ENTRYPOINT echo ${HOSTNAME}

dockerfile多個鏡像、制作鏡像后,使用如下命令啟動容器:

docker run --rm test:v1 ls

可以發現輸出的內容是主機名稱,而不是 ls 命令執行的結果。

4. 示例四:覆蓋默認的 ENTRYPOINT 命令

在啟動容器時,顯示地指定 --entrypoint 參數可以覆蓋默認的 ENTRYPOINT 命令:

docker run --rm test:v1 --entrypoint echo ${HOME}

四、了解 CMD 和 ENTRYPOINT 如何搭配使用

關于 CMD 和 ENTRYPOINT 如何搭配使用,官網給出了如下說明:

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  2. ENTRYPOINT should be defined when using the container as an executable.
  3. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
  4. CMD will be overridden when running the container with alternative arguments.

dockerfile啟動參數。The table below shows what command is executed for different ENTRYPOINT / CMD combinations:

No ENTRYPOINTENTRYPOINT exec_entry p1_entryENTRYPOINT [“exec_entry”, “p1_entry”]
No CMDerror, not allowed/bin/sh -c exec_entry p1_entryexec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”]exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”]p1_cmd p2_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd/bin/sh -c exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

總結起來的話,就是如下幾點:

  1. 如果 ENTRYPOINT 使用了 shell 模式,CMD 指令會被忽略。
  2. 如果 ENTRYPOINT 使用了 exec 模式,CMD 指定的內容被追加為 ENTRYPOINT 指定命令的參數。
  3. 如果 ENTRYPOINT 使用了 exec 模式,CMD 也應該使用 exec 模式。

本文原文鏈接:https://blog.csdn.net/xzk9381/article/details/114635083,轉載請注明出處。如有發現文章中的任何問題,歡迎評論區留言。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/177813.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息