阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

关于 Docker中 CMD 与 ENTRYPOINT 的区别

227次阅读
没有评论

共计 3546 个字符,预计需要花费 9 分钟才能阅读完成。

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

 

CMD 指令:

The main purpose of a CMD is to provide defaults for an executing container.

CMD 在容器运行的时候提供一些命令及参数,用法如下:

  1. CMD [“executable”,“param1”,“param2”] (exec form, this is the preferred form) 
  2. CMD [“param1”,“param2”] (as default parameters to ENTRYPOINT) 
  3. CMD command param1 param2 (shell form) 
  • 第一种用法:运行一个可执行的文件并提供参数。
  • 第二种用法:为 ENTRYPOINT 指定参数。
  • 第三种用法(shell form):是以”/bin/sh -c”的方法执行的命令。

 

如你指定:

  1. CMD [“/bin/echo”,“this is a echo test”] 

build 后运行(假设镜像名为 ec):

  1. docker run ec 

就会输出: this is a echo test

是不是感觉很像开机启动项,你可以暂时这样理解。

 

注意点:

docker run 命令如果指定了参数会把 CMD 里的参数覆盖:(这里说明一下,如:docker run -it Ubuntu /bin/bash 命令的参数是指 /bin/bash 而非 -it ,-it 只是 docker 的参数,而不是容器的参数,以下所说参数均如此。)

同样是上面的 ec 镜像启动:

docker run ec /bin/bash

不会 输出:this is a echo test,因为 CMD 命令被”/bin/bash”覆盖了。

 

ENTRYPOINT

字面意思是进入点,而它的功能也恰如其意。

An ENTRYPOINT allows you to configure a container that will run as an executable. 它可以让你的容器功能表现得像一个可执行程序一样。

容器功能表现得像一个可执行程序一样,这是什么意思呢?

直接给个例子好说话:

例子一:

使用下面的 ENTRYPOINT 构造镜像:

  1. ENTRYPOINT [“/bin/echo”

那么 docker build 出来的镜像以后的容器功能就像一个 /bin/echo 程序:

比如我 build 出来的镜像名称叫 imageecho,那么我可以这样用它:

  1. docker run -it imageecho“this is a test”

这里就会输出”this is a test”这串字符,而这个 imageecho 镜像对应的容器表现出来的功能就像一个 echo 程序一样。你添加的参数“this is a test”会添加到 ENTRYPOINT 后面,就成了这样 /bin/echo“this is a test”。现在你应该明白进入点的意思了吧。

 

例子二:

ENTRYPOINT [“/bin/cat”]

构造出来的镜像你可以这样运行(假设名为 st):

  1. docker run -it st /etc/fstab 

这样相当:/bin/cat /etc/fstab 这个命令的作用。运行之后就输出 /etc/fstab 里的内容。

 

ENTRYPOINT 有两种写法:

写法一:

  1. ENTRYPOINT [“executable”“param1”“param2”] (the preferred exec form) 

写法二:

  1. ENTRYPOINT command param1 param2 (shell form) 

你也可以在 docker run 命令时使用–entrypoint 指定(但是只能用写法一)。

 

下面是我把 ENTRYPOINT 设为 [“/bin/sh -c”] 时候运行的情况:

  1. linux-oj9e:/home/lfly/project/docker # docker run -it t2 /bin/bash 
  2. root@4c8549e7ce3e:/# ps 
  3. PID TTY TIME CMD 
  4. 1 ? 00:00:00  sh 
  5. 9 ? 00:00:00  bash 
  6. 19 ? 00:00:00  ps 

可以看到 PID 为 1 的进程运行的是 sh,而 bash 只是 sh 的一个子进程,/bin/bash 只是作为 /bin/sh - c 后面的参数。

 

CMD 可以为 ENTRYPOINT 提供参数,ENTRYPOINT 本身也可以包含参数,但是你可以把那些可能需要变动的参数写到 CMD 里而把那些不需要变动的参数写到 ENTRYPOINT 里面例如:

  1. FROM ubuntu:14.10 
  2. ENTRYPOINT [“top”“-b”]   
  3. CMD [“-c”

把可能需要变动的参数写到 CMD 里面。然后你可以在 docker run 里指定参数,这样 CMD 里的参数 (这里是 -c) 就会被覆盖掉而 ENTRYPOINT 里的不被覆盖。

 

注意点1:

ENTRYPOINT 有两种写法,第二种 (shell form) 会屏蔽掉 docker run 时后面加的命令和 CMD 里的参数。

 

注意点2:

网上有资料说 ENTRYPOINT 的默认值是[”/bin/sh -c”],但是笔者在试验的时候得到的结果并不是这样的。

笔者使用 ENTRYPOINT [“/bin/sh -c”] 指令构造一个以 /bin/sh - c 为进入点的镜像,命名为 sh,然后我可以这样运行:

  1. docker run -it sh“while(ture) do echo loop; done”

运行结果就是无限输出 loop。但如果直接运行一个 ubuntu:14.10 镜像,情况不是这样的:

  1. docker run -it ubuntu:14.10while(ture) do echo loop; done”

得到这样的错误:

  1. linux-oj9e:/home/lfly # docker run -it ubuntu:14.10while(truedo echo this; done”2014/11/16 18:07:53 Error response from daemon: Cannot start container 4bfe9c6faeec3ed465788a201a2f386cb1af35aba197dbc78b87c0d5dda1f88e: exec:“while(truedo echo this; done”: executable file not found in $PATH 

可以猜想默认情况下 ENTRYPOINT 并不是[“/bin/sh -c”]。

而且直接运行 ubuntu:14.10 列出程序也可以看到 PID 为 1 的程序并不是 sh。所以更否定了网友的说法,ENTRYPOINT 并不默认为[“/bin/sh -c”]。

更多 Docker 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm

Ubuntu 使用 VNC 运行基于 Docker 的桌面系统  http://www.linuxidc.com/Linux/2015-08/121170.htm

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

Ubuntu 16.04 上 Docker 使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链���地址:http://www.linuxidc.com/Linux/2017-03/141819.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计3546字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中