Dockerfile中cmd和entrypoint的区别

rur96b6h  于 2023-04-11  发布在  Docker
关注(0)|答案(1)|浏览(139)

我刚接触docker,有一个关于Dockerfile的简单问题。我们可以在Dockerfile中编写entrypoint和CMD。似乎ENTRYPOINT是在创建容器时执行的。而CMD是在启动容器时执行的。这是真的吗?

7kqas0il

7kqas0il1#

不完全是
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如何交互”部分:

  • Dockerfile应至少指定CMDENTRYPOINT命令之一。
  • 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"](一个命令,一个参数)
  • 如果否ENTRYPOINTexec_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"]
  • 如果否ENTRYPOINTp1_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

相关问题