Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

介绍容器设计用于运行特定的任务和进程,而不是用于托管操作系统。你创建一个容器来为单个单元任务提供服务。一旦它完成给定的任务,它就会停止。因此,容器生命周期取决于其内部正在进行的过程。一旦进程停止,容器也会停止。
Dockerfile 定义了这个过程。它是一个由有关如何构建 Docker 镜像的指令组成的脚本。在这个脚本中,有两种类型的指令可以定义容器中运行的进程:

  • Entrypoint
  • CMD
Docker CMD与Entrypoint命令有什么区别?在本文中,我们将解释 Docker ENTRYPOINT 和 CMD 之间的区别以及何时使用哪个 Docker 指令。
Docker Entrypoint与 CMD:解决困境  简而言之,CMD定义了容器的默认命令和/或参数。如果你需要用户可以轻松覆盖的默认命令,则 CMD 是最好使用的指令。如果一个 Dockerfile 有多个 CMD,它只会应用最后一个的指令。
另一方面,当你要定义具有特定可执行文件的容器时,首选ENTRYPOINT。除非添加标志,否则在启动容器时不能覆盖 ENTRYPOINT--entrypoint
Docker CMD与Entrypoint命令应该使用哪个?如果你需要具有指定可执行文件和可以轻松修改的默认参数的容器,请将ENTRYPOINT 与 CMD 结合使用。例如,在容器化应用程序时, 使用ENTRYPOINT和CMD来设置特定于环境的变量。
Shell 和 Exec 形式Docker CMD与Entrypoint有什么不同?在我们开始之前,讨论指令的形式很重要。Docker ENTRYPOINT 和 CMD 可以有两种形式:
  • Shell形式
  • Exec形式
shell 形式的任何命令的语法是:
< instruction> < command>

exec 形式的指令的语法是:
< instruction> [ "executable", "parameter"]

你可以以两种形式编写 Docker CMD/ENTRYPOINT 指令:
  • CMD echo "Hello World"  (Shell形式)
  • CMD ["echo", "Hello World"]  (Exec形式)
  • ENTRYPOINT echo "Hello World"  (Shell形式)
  • ENTRYPOINT ["echo", "Hello World"]  (Exec形式)
但是,请尝试将所有指令保留在exec 形式中,以防止潜在的性能问题。
Docker CMDDocker CMD与Entrypoint命令有什么区别?Docker CMD定义了 Docker 镜像的默认可执行文件。你可以将此镜像作为容器的基础运行,而无需添加命令行参数。在这种情况下,容器运行 CMD 命令指定的进程。
CMD 指令仅run在启动容器时没有向命令添加参数的情况下使用。因此,如果向命令添加参数,则会覆盖 CMD。
为了向你展示 CMD 的工作原理,我们将创建一个带有 CMD 指令的示例容器。
使用 CMD 创建 Dockerfile 并构建镜像
1. 首先创建一个新MyDockerImage文件夹来存储你的镜像:
sudo mkdir MyDockerImage

2. 进入该文件夹并创建一个新的 Dockerfile:
cd MyDockerImage

sudo touch Dockerfile

3. 使用你喜欢的文本编辑器打开 Dockerfile:
nano Dockerfile

4. 然后,将以下内容添加到文件中:
FROM ubuntu MAINTAINER sofija RUN apt-get update CMD [ "echo", "Hello World"]

Docker CMD与Entrypoint有什么不同?在上面的内容中,可以看到我们在Hello World没有指定命令的情况下,在容器启动时使用了CMD指令来回显消息。
5.保存并退出文件。
6. 下一步是从新制作的 Dockerfile 构建一个 Docker 镜像。由于我们还在MyDockerImage目录中,所以不需要指定 Dockerfile 的位置,只需运行以下命令构建镜像:
sudo docker build .

【Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)】7. 输出将告诉你容器的名称。你可以通过运行以下命令来检查它是否在本地存储的镜像中可用:
sudo docker images

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
注意:在这一步中,你已经创建了一个 Docker 镜像并将其存储到你的本地存储库中。如果你想了解有关此过程的更多信息,请参阅我们关于使用 Dockerfiles 创建 Docker 镜像的文章。
使用 CMD 运行 Docker 容器
Docker CMD与Entrypoint命令应该使用哪个:要查看 CMD 的实际效果,我们将根据上一步中制作的镜像创建一个容器。
使用以下命令运行容器:
sudo docker run [ image_name]

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
由于没有命令行参数,容器将运行默认的 CMD 指令并显示Hello World消息。但是,如果在启动容器时添加参数,它将覆盖 CMD 指令。
例如,将主机名参数添加到docker run 命令:
sudo docker run [ image_name] hostname

Docker 将运行容器和hostname命令,而不是 CMD 的 echo 命令。你可以在输出中看到这一点。
Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
Docker EntrypointDocker CMD与Entrypoint命令有什么区别?ENTRYPOINT 是用于配置容器运行方式的另一条指令。就像 CMD 一样,你需要指定命令和参数。
CMD 和 ENTRYPOINT 有什么区别?你不能通过向命令添加命令行参数来覆盖 ENTRYPOINT 指令docker run。通过选择此说明,你暗示该容器是专门为此类用途而构建的。
请继续阅读以了解我们如何在容器创建中应用 ENTRYPOINT。
使用 ENTRYPOINT 创建 Dockerfile 并构建镜像
1.使用CMD部分创建的Dockerfile,编辑文件修改指令。使用文本编辑器打开现有文件:
sudo nano Dockerfile

2.通过将CMD命令替换为ENTRYPOINT来编辑内容:
FROM ubuntu MAINTAINER sofija RUN apt-get update ENTRYPOINT [ "echo", "Hello World"]

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
3.保存并关闭文件。
使用 ENTRYPOINT 运行 Docker 容器
1. 使用以下命令构建新镜像:
sudo docker build .

2. 输出应显示你已成功以给定名称构建新镜像。现在让我们将它作为容器运行而不添加任何命令行参数:
sudo docker run [ container_name]

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
输出将与 CMD 相同。这是因为我们没有向 run 命令添加任何参数。
3、Docker CMD与Entrypoint有什么不同?要查看ENTRYPOINT是如何工作的,需要在启动容器时添加一个参数。使用与上一步相同的命令,并在容器名称后添加一些内容:
sudo docker run [ container_name] KnowledgeBase

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
如你所见,Docker 没有覆盖回显 Hello World 的初始指令。它只是将新参数添加到现有命令中。
注意:有一种方法可以覆盖 ENTRYPOINT 指令——你需要在运行命令--entrypoint之前添加标志container_name
尽管你可以在两种形式中使用 ENTRYPOINT 和 CMD,但通常建议坚持使用 exec 形式。这是更可靠的解决方案,因为Shell形式有时会在此过程中带来微妙的问题。
使用 CMD 的 Docker EntrypointDocker CMD与Entrypoint命令有什么区别?到目前为止,你已经看到,ENTRYPOINT 和 CMD 很相似,但又不一样。更重要的是,这两个指令并不相互排斥。没错,你的 Dockerfile 中可以同时拥有两者。
在许多情况下,结合 CMD 和 ENTRYPOINT 将是你的 Docker 容器的最佳解决方案。在这种情况下,可执行文件使用 ENTRYPOINT 定义,而CMD 指定默认参数。
Docker CMD与Entrypoint命令应该使用哪个:如果你同时使用这两个指令,请确保将它们保存在 exec 格式中。
请继续阅读以了解 ENTRYPOINT 和 CMD 如何在我们的示例中协作。
使用Entrypoint和 CMD 运行容器
1. 首先,我们将修改现有的 Dockerfile,使其包含这两个指令。使用以下命令打开文件:
sudo nano Dockerfile

2. 该文件应包含一条指定可执行文件的 ENTRYPOINT 指令,以及一条定义默认参数的 CMD 指令,如果没有向运行命令添加其他参数,则应出现该默认参数:
FROM ubuntu MAINTAINER sofija RUN apt-get update ENTRYPOINT [ "echo", "Hello"] CMD [ "World"]

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
3. 现在,从修改后的 Dockerfile 构建一个新镜像:
sudo docker build .

4. 让我们通过不带任何参数运行容器来测试它。输入命令:
sudo docker run [ container_name]

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
它将返回消息Hello World。但是,当我们向 docker run 命令添加参数时会发生什么?
5. 再次使用相同的命令,但这次将你的名字添加到运行命令中:
sudo docker run [ container_name] [ your_name]

Docker CMD与Entrypoint命令有什么区别(应该使用哪个?)

文章图片
输出现在已更改为Hello [your_name](在我的情况下,它是Hello Sofija)。这是因为你不能覆盖 ENTRYPOINT 指令,而使用 CMD 你可以轻松地做到这一点。
结论Docker CMD与Entrypoint命令有什么区别?看完这篇文章,你应该对ENTRYPOINT和CMD的区别有了更好的了解。探索两者的使用并对其进行试验以找到最适合你的解决方案。
如果你不熟悉Docker,请查看我们的Docker 备忘单,其中包含所有常用命令。我们相信它会派上用场!

    推荐阅读