在dockefile中cmd和入口点之间的差异

ric*_*ard 1 docker

我是docker的新手,对dockfile有一个简单的问题.我们可以在dock文件中编写入口点和CMD.似乎在创建容器期间执行入口点.并且在启动容器期间执行CMD.这是真的?

Von*_*onC 5

不完全是:

ENTRYPOINT配置将作为可执行文件运行的容器.
所以它总是被执行(或默认/bin/sh -c是).

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)
Run Code Online (Sandbox Code Playgroud)

命令行参数docker run <image>将附加在exec表单中的所有元素之后ENTRYPOINT,并将覆盖使用CMD指定的所有元素.

shell表单阻止使用任何CMD或运行命令行参数,但缺点是您ENTRYPOINT将作为子命令启动/bin/sh -c,它不传递信号.
这意味着可执行文件不是容器的PID 1 - 并且不会接收Unix信号 - 因此您的可执行文件将不会从中接收SIGTERM docker stop <container>.

您可以查看CMD作为参数ENTRYPOINT.
如果没有入口点(默认命令为" /bin/sh -c"),则CMD可以包含可执行文件.
如果ENTRYPOINT已运行可执行文件,则CMD参数是此命令的参数(如果docker run在没有其他参数的情况下使用).


随着docker start,如中提到的问题1437时,ENTRYPOINT被执行,但只有从参数CMD(所以CMD被使用,但你不能用你自己的命令行参数覆盖它).
如果你想使用CMD,你需要docker run,而不是docker start.

实际上有一个PR正在进行中(PR 19746),它允许docker start命令采用optional --cmd(-c)标志来指定要使用的cmd,而不是cmd/entrypoint中的默认cmd.


官方Dockerfile文档现在有一个部分" 了解如何CMD和入口点互动 ":

  • Dockerfile应至少指定一个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