CMD与ENTRYPOINT的区别与联系

在Deckerfile中最容易混淆的两个指令就是CMDENTRYPOINT,今天我们就来详细分析这两个指令具体是用来做什么的。

一. 指令的定义
  • CMD指令的定义

下面我们来看官方给出的定义:

The main purpose of a CMD is to provide defaults for an executing container. 
These defaults can include an executable, or they can omit the executable, in
which case you must specify an ENTRYPOINT instruction as well.

CMD主要目的是为执行中的容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情下,您还必须指定一条ENTRYPOINT指令。

从上面的定义我可以看出分两种情况,一种是给ENTRYPOINT指令提供默认的参数,一种是指定可执行文件,作为容器启动后执行的命令;
下面简单看一下该指令的用法

CMD ["executable","param1","param2"] (exec模式, 这是推荐的方式)
CMD ["param1","param2"] (作为 ENTRYPOINT 的默认参数)
CMD command param1 param2 (shell模式)

如果Dockerfile中包含多条CMD指令,则只有最后一条指令生效。

  • ENTRYPOINT指令的定义
An ENTRYPOINT allows you to configure a container that will run as an executable.

也就是说ENTRYPOINT才是容器执行的入口,
下面介绍一下该指令的用法:

ENTRYPOINT ["executable", "param1", "param2"] (exec模式,推荐的方式)
ENTRYPOINT command param1 param2 (shell模式)
  • exec形式的ENTRYPOINT在执行命令docker run image时。命令行参数将附加在ENTRYPOINT指定的所有元素之后,并将覆盖使用CMD指定的所有参数,这允许将参数传递到ENTRYPOINT,即docker run image -d-d参数传递给ENTRYPOINT。 您可以使用docker run --entrypoint覆盖掉ENTRYPOINT指令。
  • shell形式的ENTRYPOINT可防止使用任何CMD或运行命令行带入的参数,但其缺点是ENTRYPOINT将作为/bin/sh -c的子命令启动,该子命令不传递信号。因此您的可执行文件将不会从docker stop container接收到SIGTERM。
  • 如果Dockerfile中包含多条ENTRYPOINT指令,则只有最后一条指令生效。
    您可以使用ENTRYPOINT的exec形式来设置相当稳定的默认命令和参数,然后使用CMD来设置更可能被更改的其他默认值。

二. CMD和ENTRYPOINT如何相互作用
  • Dockerfile中应该至少指定CMDENTRYPOINT指令中的一种;

  • 当使用容器作为可执行文件时应定义ENTRYPOINT

  • CMD应该被用作在容器中定义ENTRYPOINT命令或执行临时命令默认参数。

  • 当使用其他参数运行容器时CMD 将被覆盖

注意:如果CMD在基础镜像已有定义,则设置ENTRYPOINT会将CMD重置为空值。在这种情况下,CMD必须在当前镜像中重新定义一个值。


三. CMD和ENTRYPOINT的区别与联系
  • 相同点
    • 用法相似,都可以指定shell或exec函数调用的方式执行命令;
    • 当存在多个CMD指令或ENTRYPOINT指令时,只有最后一个生效;
  • 不同点
    • 容器启动时,CMD指令指定的启动命令可以被docker run指定的命令覆盖,而ENTRYPOINT指令指定的启动命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数;
    • CMD指令可以作为ENTRYPOINT指令的默认参数。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章