我刚接触docker,有一个关于Dockerfile的简单问题。我们可以在Dockerfile中编写entrypoint和CMD。似乎ENTRYPOINT是在创建容器时执行的。而CMD是在启动容器时执行的。这是真的吗?
7kqas0il1#
不完全是ENTRYPOINT配置了一个作为可执行文件运行的容器。所以它总是被执行(或者默认的/bin/sh -c是)。
ENTRYPOINT
/bin/sh -c
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred) ENTRYPOINT command param1 param2 (shell form)
docker run <image>的命令行参数将附加在exec表单ENTRYPOINT中的所有元素之后,并将覆盖使用CMD指定的所有元素。shell形式防止使用任何CMD或run命令行参数,但缺点是ENTRYPOINT将作为/bin/sh -c的子命令启动,而/bin/sh -c不传递信号。这意味着可执行文件将不是容器的PID 1 -并且不会接收Unix信号-因此您的可执行文件将不会从docker stop <container>接收SIGTERM。您可以将CMD视为ENTRYPOINT的参数。如果没有入口点(默认命令是“/bin/sh -c“),CMD可以包含可执行文件。如果ENTRYPOINT已经运行可执行文件,则CMD参数是此命令的参数(如果使用docker run而不使用其他参数)。使用docker start时,如issue 1437中所述,ENTRYPOINT会被执行,但只能使用来自CMD的参数(因此使用了CMD,但您不能在命令行中使用自己的参数覆盖它)。如果你想使用CMD,你需要docker run,而不是docker start。实际上最近有一个PR正在进行中(PR 19746),它允许docker start命令使用一个可选的--cmd(-c)标志来指定要使用的cmd,而不是cmd/entrypoint中的默认值。Official Dockerfile documentation现在有一个“了解CMD和ENTRYPOINT如何交互”部分:
docker run <image>
CMD
docker stop <container>
docker run
docker start
--cmd
-c
这意味着,如果您的Dockerfile包含:
*否CMD:
ENTRYPOINT exec_entry p1_entry
/bin/sh -c exec_entry p1_entry
ENTRYPOINT ["exec_entry", "p1_entry"]
exec_entry p1_entry
CMD ["exec_cmd", "p1_cmd"]
exec_cmd p1_cmd
/bin/sh -c exec_entry p1_entry exec_cmd p1_cmd
exec_entry p1_entry exec_cmd p1_cmd
CMD ["p1_cmd", "p2_cmd"]
p1_cmd p2_cmd
/bin/sh -c exec_entry p1_entry p1_cmd p2_cmd
ENTRYPOINT [“exec_entry”, “p1_entry”]
exec_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_entry /bin/sh -c exec_cmd p1_cmd
exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
1条答案
按热度按时间7kqas0il1#
不完全是
ENTRYPOINT
配置了一个作为可执行文件运行的容器。所以它总是被执行(或者默认的
/bin/sh -c
是)。docker run <image>
的命令行参数将附加在exec表单ENTRYPOINT
中的所有元素之后,并将覆盖使用CMD指定的所有元素。shell形式防止使用任何
CMD
或run命令行参数,但缺点是ENTRYPOINT
将作为/bin/sh -c
的子命令启动,而/bin/sh -c
不传递信号。这意味着可执行文件将不是容器的PID 1 -并且不会接收Unix信号-因此您的可执行文件将不会从
docker stop <container>
接收SIGTERM。您可以将
CMD
视为ENTRYPOINT
的参数。如果没有入口点(默认命令是“
/bin/sh -c
“),CMD
可以包含可执行文件。如果
ENTRYPOINT
已经运行可执行文件,则CMD参数是此命令的参数(如果使用docker run
而不使用其他参数)。使用
docker start
时,如issue 1437中所述,ENTRYPOINT
会被执行,但只能使用来自CMD
的参数(因此使用了CMD
,但您不能在命令行中使用自己的参数覆盖它)。如果你想使用CMD,你需要
docker run
,而不是docker start
。实际上最近有一个PR正在进行中(PR 19746),它允许docker start命令使用一个可选的
--cmd
(-c
)标志来指定要使用的cmd,而不是cmd/entrypoint中的默认值。Official Dockerfile documentation现在有一个“了解CMD和ENTRYPOINT如何交互”部分:
CMD
或ENTRYPOINT
命令之一。ENTRYPOINT
应该在使用容器作为可执行文件时定义。CMD
应用作为ENTRYPOINT
命令或在容器中执行ad-hoc命令定义默认参数的方法。CMD
将在使用替代参数运行容器时被覆盖。这意味着,如果您的Dockerfile包含:
*否
CMD
:ENTRYPOINT
:错误,不允许ENTRYPOINT exec_entry p1_entry
表示/bin/sh -c exec_entry p1_entry
ENTRYPOINT ["exec_entry", "p1_entry"]
表示exec_entry p1_entry
*
CMD ["exec_cmd", "p1_cmd"]
(一个命令,一个参数)ENTRYPOINT
:exec_cmd p1_cmd
,ENTRYPOINT exec_entry p1_entry
表示/bin/sh -c exec_entry p1_entry exec_cmd p1_cmd
ENTRYPOINT ["exec_entry", "p1_entry"]
表示exec_entry p1_entry exec_cmd p1_cmd
*
CMD ["p1_cmd", "p2_cmd"]
ENTRYPOINT
:p1_cmd p2_cmd
ENTRYPOINT exec_entry p1_entry
表示/bin/sh -c exec_entry p1_entry p1_cmd p2_cmd
(良好)ENTRYPOINT [“exec_entry”, “p1_entry”]
表示exec_entry p1_entry p1_cmd p2_cmd
*
CMD exec_cmd p1_cmd
:ENTRYPOINT
:/bin/sh -c exec_cmd p1_cmd
ENTRYPOINT exec_entry p1_entry
表示/bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
ENTRYPOINT [“exec_entry”, “p1_entry”]
表示exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd