昨天用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命令的主要用途。下面就看看具体用法。

总共有三种用法:

The CMD instruction has three forms:

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

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

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

FROM centos

CMD echo "hello cmd!"

运行:

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

FROM centos

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才是正统地用于定义容器启动以后的执行体的,其实我们从名字也可以理解,这个是容器的“入口”。

有两种用法:

ENTRYPOINT has two forms:

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)

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

下面看几个例子。

dockerfile为:

FROM centos

CMD ["p in cmd"]
ENTRYPOINT ["echo"]

如果run不带参数:

如果run带参数:

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

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

FROM centos

CMD ["p in cmd"]
ENTRYPOINT echo

cmd的参数没有被打印。

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

感谢:https://blog.csdn.net/u010900754/article/details/78526443

docker CMD 和 ENTRYPOINT 区别的更多相关文章

  1. Docker 的CMD与ENTRYPOINT区别

    我们在构建一个docker镜像的时候,Dockerfile里面有两个命令会引起我们的注意,它们就是 CMD 和 ENTRYPOINT,看起来很相似,实际上并非如此. 一.CMD 顾名思义就是允许用户指 ...

  2. [转]【docker】CMD ENTRYPOINT 区别

    本文转自:https://blog.csdn.net/u010900754/article/details/78526443 昨天用Dockerfile来启动mongodb的集群,启动参数--repl ...

  3. Docker系列(23)- CMD和ENTRYPOINT的区别

    CMD和ENTRYPOINT的区别 CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 测试CMD ...

  4. Docker | dockerfile构建centos镜像,以及CMD和ENTRYPOINT的区别

    构建自己的centos镜像 docker pull centos下载下来的镜像都是基础版本,缺少很多常用的命令功能,比如:ll.vim等等, 下面介绍制作一个功能较全的自己的centos镜像. 步骤 ...

  5. 论docker中 CMD 与 ENTRYPOINT 的区别

    Dockerfile里有 CMD 与 ENTRYPOINT 两个功能咋看起来很相似的指令,开始的时候觉得两个互用没什么所谓,但其实并非如此: CMD指令: The main purpose of a ...

  6. 论docker中 CMD 与 ENTRYPOINT 的区别(转)

    Dockerfile 用于自动化构建一个docker镜像.Dockerfile里有 CMD 与 ENTRYPOINT 两个功能咋看起来很相似的指令,开始的时候觉得两个互用没什么所谓,但其实并非如此: ...

  7. RUN vs CMD vs ENTRYPOINT - 每天5分钟玩转 Docker 容器技术(17)

    RUN.CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆.本节将通过实践详细讨论它们的区别. 简单的说: RUN 执行命令并创建新的镜像层,RUN 经常用于 ...

  8. Docker入门之---ENTRYPOINT和CMD

    1. 前言  ENTRYPOINT 和CMD 都是Dockerfile 中的命令,两者都是用来:指定默认的容器的主进程的启动命令.那么接下来就介绍一下这两者在Dockerfile 中,以及Docker ...

  9. CMD centos7 安装 最新版本的docker -- dockerfire 原语 ENTRYPOINT - 导入镜像 tar mariadb Dockerfile 构建镜像

    yum update # vim /etc/yum.repos.d/docker.repo //添加以下内容 [dockerrepo] name=Docker Repository baseurl=h ...

随机推荐

  1. HTML5调用本地摄像头画面,拍照,上传服务器

    实现功能和适用业务 采集本地摄像头获取摄像头画面,拍照保存,上传服务器: 前端上传图片处理,展示,缩小,裁剪,上传服务器 实现步骤 调取本地摄像头(getUserMedia)/上传图片,将图片/视频显 ...

  2. Linux设备驱动程序 之 重要数据结构

    文件对象 文件对象是进程已经打开文件描述符的内存中的表示,单个文件可能有多个表示打开文件描述符的file结构: struct file { union { struct llist_node fu_l ...

  3. shell脚本备份当前日期文件

    #!/bin/bash #一月前 historyTime=$(date "+%Y-%m-%d %H" -d '1 month ago') echo ${historyTime} h ...

  4. Docker搭建ELK分析tomat日志

    最近公司的项目中用到了ELK,正好有时间自己搭建一个学习一下.在实体机或虚拟机中搭建还需要安装软件,使用docker镜像安装是省时省力的,如下是步骤. 1. 下载elasticsearch镜像: #d ...

  5. leetcode-hard-array-149. Max Points on a Line -NO

    mycode  不会.... 参考 因为每次遍历一个点,也就是i的时候,都是新建的一个lines,所以也就是考虑了k相同b不同的情况 最后gcd函数就求最大公约数,来解决斜率精度的问题 class S ...

  6. shell 脚本基础与条件判断

    #!shell脚本格式决定专业性 #!/bin/bash #filename:脚本名 #author:作者 #date:时间 #脚本作用 脚本的执行方式  #脚本名为wk.sh 绝对路径 /root/ ...

  7. 发布机制-灰度发布-例子:Windows

    ylbtech-发布机制-灰度发布-例子:Windows 在传统软件产品发布过程中(例如微软的Windows 7的发布过程中),一般都会经历Pre-Alpha.Alpha.Beta.Release c ...

  8. Linux CentOS 7修改内核启动默认顺序

    1.查看系统有几个内核 a.进入grub2.cfg文件中进行查看 b.通过grub界面查看 3.设置默认启动内核 grub2-set-default "内核版本" 配置默认内核4. ...

  9. RabbitMQ学习之:(六)Direct Exchange (转贴+我的评论)

    From: http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/ RabbitMQ fo ...

  10. RxJS 6有哪些新变化?

    我们的前端工程由Angular4升级到Angular6,rxjs也要升级到rxjs6.  rxjs6的语法做了很大的改动,幸亏引入了rxjs-compact包,否则升级工作会无法按时完成. 按照官方的 ...