在Dockerfile中,有两个命令与我类似:CMD和ENTRYPOINT。但我想它们之间有一个(微妙的)区别——否则,对同一件事使用两个命令是没有意义的。

CMD的文档状态-

CMD的主要目的是为正在执行的容器提供默认值。

对于入口点:

ENTRYPOINT帮助您配置可以作为可执行文件运行的容器。

那么,这两个命令之间有什么区别?


当前回答

代码中EntryPoint函数的注释

//入口/usr/sbin/nginx。//将入口点(默认为sh-c)设置为/usr/sbin/nginx。//将接受CMD作为/usr/sbin/nginx的参数。

文件中的另一个参考

您可以使用ENTRYPOINT的exec形式设置相当稳定的默认命令和参数,然后使用CMD设置更可能更改的其他默认值。

例子:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

Build:sudo docker Build-t ent_cmd。

CMD arguments are easy to override.

NO argument (sudo docker -it ent_cmd)                :  ping localhost 
argument    (sudo docker run -it ent_cmd google.com) :  ping google.com

.

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd

附笔:在存在EntryPoint的情况下,CMD将保存要馈送到EntryPoint的参数。如果没有EntryPoint,CMD将是将要运行的命令。

其他回答

我遇到了这个问题,一开始我发现老实说,这真的很令人困惑,我认为这种困惑来自于使用“CMD”一词,因为事实上,那里的东西充当了论据。所以挖了一点后,我明白了它是如何工作的。基本上:

ENTRYPOINT-->此处指定的是容器启动时要执行的命令。如果省略此定义,docker将使用/bin/sh-cbash来运行容器。

CMD-->这些是附加到ENTRYPOINT的参数,除非用户指定了一些自定义参数,即:docker run ubuntu<custom_CMD>在这种情况下,docker将运行ENTRYPOINT<custom_CMD>,而不是附加在CMD部分的图像上指定的内容。如果未指定ENTRYPOINT,则此处的内容将传递给/bin/sh-c,实际上作为启动容器时要执行的命令。

作为一切,最好用例子来解释发生了什么。因此,假设我使用以下规范Dockerfile创建了一个简单的docker映像:

From ubuntu
ENTRYPOINT ["sleep"]

然后我通过运行以下命令来构建它:

docker build . -t testimg

这将创建一个容器,每次运行时它都会休眠。所以,如果我按如下方式运行:

docker run testimg

我会得到以下信息:

sleep: missing operand
Try 'sleep --help' for more information.

这是因为入口点是需要参数的“sleep”命令。为了解决这个问题,我只需要提供睡眠量:

docker run testimg 5

这将正确运行,因此容器将运行,休眠5秒并退出。正如我们在这个示例中看到的,docker只是将图像名称后面的内容添加到入口点二进制docker runtestimg<my_cmd>。如果我们想将默认值(默认参数)传递给入口点,会发生什么?在这种情况下,我们只需要在CMD部分中指定它,例如:

From ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]

在这种情况下,如果用户没有传递任何参数,容器将使用默认值(10)并将其传递给入口点睡眠。

现在,让我们只使用CMD并省略ENTRYPOINT定义:

FROM ubuntu
CMD ["sleep", "5"]

如果我们重建并运行此图像,它将基本休眠5秒。

总之,您可以使用ENTRYPOINT使容器充当可执行文件。您可以使用CMD为入口点提供默认参数,或者在启动容器时运行自定义命令,该命令可以由用户从外部重写。

根据docker文档,

CMD和ENTRYPOINT指令都定义执行什么命令当运行容器时。很少有规则描述合作。Dockerfile应至少指定CMD或ENTRYPOINT命令之一。将容器用作可执行文件时,应定义ENTRYPOINT。CMD应用作为ENTRYPOINT命令或在容器当使用可选参数运行容器时,CMD将被重写。

下表显示了对不同ENTRYPOINT/CMD组合执行的命令:

--无入口点

╔════════════════════════════╦═════════════════════════════╗
║ No CMD                     ║ error, not allowed          ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD ["exec_cmd", "p1_cmd"] ║ exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD ["p1_cmd", "p2_cmd"]   ║ p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════╝

--入口点执行_入口p1_入口

╔════════════════════════════╦══════════════════════════════════╗
║ No CMD                     ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD ["exec_cmd", "p1_cmd"] ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD ["p1_cmd", "p2_cmd"]   ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_entry p1_entry   ║
╚════════════════════════════╩══════════════════════════════════╝

--入口[“exec_entry”,“p1_entry“]

╔════════════════════════════╦═════════════════════════════════════════════════╗
║ No CMD                     ║ exec_entry p1_entry                             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD ["exec_cmd", "p1_cmd"] ║ exec_entry p1_entry exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD ["p1_cmd", "p2_cmd"]   ║ exec_entry p1_entry p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝

CMD:

CMD[“executable”,“param1”,“param2”]:[“executible”,”param1“,”param2“]是第一个进程。CMD命令param1 param2:/bin/sh-c CMD命令param1 param2是第一个进程。CMD命令param1 param2从第一个进程分叉。CMD[“param1”,“param2”]:此表单用于为ENTRYPOINT提供默认参数。

ENTRYPOINT(以下列表不考虑CMD和ENTRYPOINT一起使用的情况):

ENTRYPOINT[“executable”,“param1”,“param2”]:[“executible”,”param1“,”param2“]是第一个进程。ENTRYPOINT命令param1 param2:/bin/sh-c命令param1 param2是第一个进程。命令param1 param2从第一个进程分叉。

正如creack所说,CMD是第一个开发的。然后,ENTRYPOINT被开发用于更多的定制。由于它们不是一起设计的,CMD和ENTRYPOINT之间存在一些功能重叠,这常常会让人感到困惑。

CMD和ENTRYPOINT之间的直觉差异:

ENTRYPOINT:容器启动时运行的命令。CMD:容器启动时运行的命令,或ENTRYPOINT的参数(如果指定)。

是的,这令人困惑。

在运行docker run时,可以覆盖其中任何一个。

CMD和ENTRYPOINT之间的差异示例如下:

docker run -it --rm yourcontainer /bin/bash            <-- /bin/bash overrides CMD
                                                       <-- /bin/bash does not override ENTRYPOINT
docker run -it --rm --entrypoint ls yourcontainer      <-- overrides ENTRYPOINT with ls
docker run -it --rm --entrypoint ls yourcontainer  -la  <-- overrides ENTRYPOINT with ls and overrides CMD with -la

有关CMD和ENTRYPOINT之间差异的更多信息:

docker run的参数(例如/bin/bash)会覆盖我们在Dockerfile中编写的任何CMD命令。

ENTRYPOINT不能在运行时被docker run[args]等正常命令覆盖。docker运行结束时的args[args]作为ENTRYPOINT的参数提供。通过这种方式,我们可以创建一个像ls这样的普通二进制文件的容器。

因此,CMD可以作为ENTRYPOINT的默认参数,然后我们可以从[args]重写CMD参数。

ENTRYPOINT可以用--ENTRYPOINT重写。

是的,这是个好问题。我还不完全理解,但是:

我知道ENTRYPOINT是正在执行的二进制文件。可以通过--entrypoint=“”覆盖entrypoint。

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD是容器的默认参数。如果没有入口点,默认参数是执行的命令。使用entrypoint,cmd将作为参数传递给entryppoint。您可以使用入口点模拟命令。

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

所以,主要优点是使用entrypoint可以将参数(cmd)传递给容器。要做到这一点,您需要同时使用:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

and

docker build -t=cat .

那么您可以使用:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT