docker CMD ENTRYPOINT 区别

昨天用Dockerfile来启动mongodb的集群,启动参数--replSet死活没执行,最后就决定研究一哈cmd和entrypoint。但是上网看了一些资料个人觉得讲的不好,还是没有说出根本的东西,决定自己研究并且整理一哈。

首先上docker官网:https://docs.docker.com/engine/reference/builder/#cmd

感觉官网关于这两个命令讲的简直不要太清楚。

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给出的是一个容器的默认的可执行体。也就是容器启动以后,默认的执行的命令。重点就是这个“默认”。意味着,如果docker run没有指定任何的执行命令或者dockerfile里面也没有entrypoint,那么,就会使用cmd指定的默认的执行命令执行。同时也从侧面说明了entrypoint的含义,它才是真正的容器启动以后要执行命令。

所以这句话就给出了cmd命令的一个角色定位,它主要作用是默认的容器启动执行命令。(注意不是“全部”作用)

这也是为什么大多数网上博客论坛说的“cmd会被覆盖”,其实为什么会覆盖?因为cmd的角色定位就是默认,如果你不额外指定,那么就执行cmd的命令,否则呢?只要你指定了,那么就不会执行cmd,也就是cmd会被覆盖。

明白了cmd命令的主要用途。下面就看看具体用法。

总共有三种用法:


  1. The CMD instruction has three forms:
  2. CMD ["executable","param1","param2"] (exec form, this is the preferred form)
  3. CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
  4. CMD command param1 param2 (shell form)

因为还没有讲entrypoint,所以先不看用法2。

用法3:shell form,即没有中括号的形式。那么命令command默认是在“/bin/sh -c”下执行的。比如下面的dockerfile:


  1. FROM centos
  2. CMD echo "hello cmd!"

运行:

用法1:带有中括号的形式。这时,命令没有再任何shell终端环境下,如果我们要执行shell,必须把shell加入到中括号的参数中。这种用法就像一个c语言的exec函数,意思是我们要执行一个进程。如果采用非shell的方法,那么上面的例子要修改为:


  1. FROM centos
  2. CMD ["/bin/bash", "-c", "echo ‘hello cmd!‘"]

需要注意,采用中括号形式,那么第一个参数必须是命令的全路径才行。而且,一个dockerfile至多只能有一个cmd,如果有多个,只有最后一个生效。

官网推荐采用这种方法。

当然,以上都是体现了cmd的“默认”行为。如果我们在run时指定了命令或者有entrypoint,那么cmd就会被覆盖。仍然是上面的image。run命令变了:

可以看到,最终容器里面执行的是run命令后面的命令,而不是cmd里面定义的。

接下来再看entrypoint:

An ENTRYPOINT allows you to configure a container that will run as an executable.

也就是说entrypoint才是正统地用于定义容器启动以后的执行体的,其实我们从名字也可以理解,这个是容器的“入口”。

有两种用法:


  1. ENTRYPOINT has two forms:
  2. ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
  3. ENTRYPOINT command param1 param2 (shell form)

命令行和shell。

先看命令行模式,也就是带中括号的。和cmd的中括号形式是一致的,但是这里貌似是在shell的环境下执行的,与cmd有区别。如果run命令后面有东西,那么后面的全部都会作为entrypoint的参数。如果run后面没有额外的东西,但是cmd有,那么cmd的全部内容会作为entrypoint的参数,这同时是cmd的第二种用法。这也是网上说的entrypoint不会被覆盖。当然如果要在run里面覆盖,也是有办法的,使用--entrypoint即可。

下面看几个例子。

dockerfile为:


  1. FROM centos
  2. CMD ["p in cmd"]
  3. ENTRYPOINT ["echo"]

如果run不带参数:

如果run带参数:

而且,确实entrypoint的中括号形式下,command是在shell环境下运行的,否则这里的echo是无法被执行的。

第二种是shell模式的。在这种模式下,任何run和cmd的参数都无法被传入到entrypoint里。官网推荐第一种用法。


  1. FROM centos
  2. CMD ["p in cmd"]
  3. ENTRYPOINT echo

cmd的参数没有被打印。

总结下一般该怎么使用:一般还是会用entrypoint的中括号形式作为docker 容器启动以后的默认执行命令,里面放的是不变的部分,可变部分比如命令参数可以使用cmd的形式提供默认版本,也就是run里面没有任何参数时使用的默认参数。如果我们想用默认参数,就直接run,否则想用其他参数,就run 里面加参数。

原文地址:https://www.cnblogs.com/LucasSong/p/12701434.html

时间: 2024-08-30 02:57:29

docker CMD ENTRYPOINT 区别的相关文章

[转帖]Dockerfile: ENTRYPOINT和CMD的区别

Dockerfile: ENTRYPOINT和CMD的区别 https://zhuanlan.zhihu.com/p/30555962 在我们查阅Dockerfile的官方文档时, 有可能发现一些命令的功能重复(至少看起来干的事情差不多), 我已经在上文分析过ADD和COPY命令的区别(他们功能类似), 现在我们分析另外2个命令, 他们的功能也非常类似, 是CMD和ENTRYPOINT. 尽管ENTRYPOINT和CMD都是在docker image里执行一条命令, 但是他们有一些微妙的区别.

FW: Dockerfile RUN, CMD & ENTRYPOINT

Dockerfile RUN, CMD & ENTRYPOINT 在使用Dockerfile创建image时, 有几条指令比较容易混淆, RUN, CMD, ENTRYPOINT. RUN是在building image时会运行的指令, 在Dockerfile中可以写多条RUN指令. CMD和ENTRYPOINT则是在运行container 时会运行的指令, 都只能写一条, 如果写了多条, 则最后一条生效. CMD和ENTRYPOINT的区别是: CMD在运行时会被command覆盖, ENTR

Docker CMD ENTRYPOING 和Kubernetes command args对比

Docker CMD ENTRYPOING 和Kubernetes command args对比 exec 模式 使用 exec 模式时,容器中的任务进程就是容器内的 1 号进程 shell 模式 使用 shell 模式时,docker 会以 /bin/sh -c "task command" 的方式执行任务命令.也就是说容器中的 1 号进程不是任务进程而是 bash 进程 CMD 指令 CMD 指令的目的是:为容器提供默认的执行命令. CMD 指令有三种使用方式,其中的一种是为 EN

Docker CMD(命令)和 ARGS(参数)使用整理

Docker CMD(命令)和 ARGS(参数)使用整理 总览 K8S集群创建Pod时,可以为其下的容器设置启动时要执行的命令及其参数.设置命令,就填写在配置文件的command字段下,如果要设置命令的参数,就填写在配置文件的args字段下.一旦Pod创建完成,该命令及其入参无法再进行更改. 配置文件中设置了容器启动时要执行的命令及其参数,那么容器镜像中自带的命令 与参数将会被覆盖而不再执行.如果配置文件中只是设置了入参,却没有设置其对应的命令,那么容器镜像中自带的命令会使用该新参数作为其执行时

docker save与docker export的区别

在http://chy940405.blog.51cto.com/11344281/1981804 这篇文章中分享了docker 基本操作Ⅱ(关于镜像操作),其中有一个问题就是docker save和docker export都能导出镜像包,咋看起来区别似乎不大,如下就来介绍两者的区别,适用于什么场景? - docker save > docker save的应用场景是,如果你的应用是使用docker-compose.yml编排的多个镜像组合,但你要部署的客户服务器并不能连外网.这时,你可以使用

Dockerfile中ENTRYPOINT 和 CMD的区别

CMD 指令 ENTRYPOINT 指令 两者联合使用技巧 在Docker的系统学习教程中我们了解到使用Dockerfile构建Docker镜像为一个规范的方式,根据Dockerfile可以了解镜像中安装的组件的详细内容.Dockerfile一般由四部分组成:第一,构建的基础镜像:第二,镜像构建者的信息:第三,构建镜像过程中镜像层添加指令:第四,由该镜像启动容器时执行的程序.本篇文章中涉及到的ENTRYPOINT 和CMD 属于Dockerfile中的最后一部分,这两个Dockerfile指令是

docker中entrypoint 和 CMD的执行总结

网上关于CMD和entrypoint的相关介绍很多,在实际工程中也确实需要了解,经过总结,有如下重点 如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略. 如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效. 在Dockerfile中,只能有一个ENTRYPOINT指令,如果有多个ENTRYPOINT指令则以最后一个为准. 如果镜像中设定了ENTRYPOINT,那么命令中的CMD也可以作为参数追加到ENTRYPOINT中. entrypoint

Docker CMD in detail

CMD CMD 指令就是用于指定默认的容器主进程的启动命令的,我们直接 docker run -it ubuntu 的话,会直接进入 bash.我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release.这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息. 在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 ",

commonjs amd cmd的区别

一篇博客告诉你三者的区别:http://zccst.iteye.com/blog/2215317 告诉你三者同requirejs seajs的区别:http://blog.chinaunix.net/uid-26672038-id-4112229.html 本人道听途生的: commonjs的规范在node还没有产生以前,就有了,commonjs作为一个后端的规范,虽然后端的Js以前发展缓慢,但是commonjs这个规范还是比较完善的,随着Node的普及,commonjs被完全遵从和实现,com