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

2021年11月21日03:29:14 发表评论 1,868 次浏览

介绍

容器设计用于运行特定的任务和进程,而不是用于托管操作系统。你创建一个容器来为单个单元任务提供服务。一旦它完成给定的任务,它就会停止。因此,容器生命周期取决于其内部正在进行的过程。一旦进程停止,容器也会停止。

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 结合使用。例如,在容器化应用程序时, 使用ENTRYPOINTCMD来设置特定于环境的变量。

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 CMD

Docker 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 .

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 Entrypoint

Docker 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 Entrypoint

Docker 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 备忘单,其中包含所有常用命令。我们相信它会派上用场!

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: