设为首页 收藏本站
查看: 774|回复: 0

[经验分享] RUN vs CMD vs ENTRYPOINT

[复制链接]

尚未签到

发表于 2017-12-5 16:48:19 | 显示全部楼层 |阅读模式
RUN、CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆。本节将通过实践详细讨论它们的区别。
  简单的说:

  •   RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。
  •   CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。
  •   ENTRYPOINT 配置容器启动时运行的命令。
  下面我们详细分析。
  Shell 和 Exec 格式
  我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式,二者在使用上有细微的区别。
  Shell 格式
  <instruction> <command>
  
例如:

  RUN apt-get install python3  
  CMD echo "Hello world"  
  ENTRYPOINT echo "Hello world"
  
当指令执行时,shell 格式底层会调用 /bin/sh -c <command>。

  例如下面的 Dockerfile 片段:
  ENV name Cloud Man  
  ENTRYPOINT echo "Hello, $name"
  
执行 docker run <image> 将输出:
  Hello, Cloud Man
  注意环境变量 name 已经被值 Cloud Man 替换。
  下面来看 Exec 格式。
  Exec 格式
  <instruction> ["executable", "param1", "param2", ...]
  例如:
  RUN ["apt-get", "install", "python3"]  
  CMD ["/bin/echo", "Hello world"]  
  ENTRYPOINT ["/bin/echo", "Hello world"]
  当指令执行时,会直接调用 <command>,不会被 shell 解析。
例如下面的 Dockerfile 片段:
  ENV name Cloud Man  
  ENTRYPOINT ["/bin/echo", "Hello, $name"]
  运行容器将输出:
  Hello, $name
  注意环境变量“name”没有被替换。
如果希望使用环境变量,照如下修改
  ENV name Cloud Man  
  ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]
  运行容器将输出:
  Hello, Cloud Man
  CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。
  RUN
  RUN 指令通常用于安装应用和软件包。
  RUN 在当前镜像的顶部执行命令,并通过创建新的镜像层。Dockerfile 中常常包含多个 RUN 指令。
  RUN 有两种格式:

  •   Shell 格式:RUN
  •   Exec 格式:RUN ["executable", "param1", "param2"]
  下面是使用 RUN 安装多个包的例子:
  RUN apt-get update && apt-get install -y \  
    bzr \
    cvs \
    git \
    mercurial \
    subversion
  注意:apt-get update 和 apt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。
  CMD
  CMD 指令允许用户指定容器的默认执行的命令。
  此命令会在容器启动且 docker run 没有指定其他命令时运行。

  •   如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
  •   如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。
  CMD 有三种格式:

  •   Exec 格式:CMD ["executable","param1","param2"]
    这是 CMD 的推荐格式。
  •   CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。
  •   Shell 格式:CMD command param1 param2
  Exec 和 Shell 格式前面已经介绍过了。
第二种格式 CMD ["param1","param2"] 要与 Exec 格式 的 ENTRYPOINT 指令配合使用,其用途是为 ENTRYPOINT 设置默认的参数。我们将在后面讨论 ENTRYPOINT 时举例说明。
  下面看看 CMD 是如何工作的。Dockerfile 片段如下:
  CMD echo "Hello world"
  运行容器 docker run -it [image] 将输出:
  Hello world
  但当后面加上一个命令,比如 docker run -it [image] /bin/bash,CMD 会被忽略掉,命令 bash 将被执行:
  root@10a32dc7d3d3:/#
  ENTRYPOINT
  ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行。
  ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
  ENTRYPOINT 有两种格式:

  •   Exec 格式:ENTRYPOINT ["executable", "param1", "param2"] 这是 ENTRYPOINT 的推荐格式。
  •   Shell 格式:ENTRYPOINT command param1 param2
  在为 ENTRYPOINT 选择格式时必须小心,因为这两种格式的效果差别很大。
  Exec 格式
  ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。
  ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。
  比如下面的 Dockerfile 片段:
  ENTRYPOINT ["/bin/echo", "Hello"]  
  CMD ["world"]
  当容器通过 docker run -it [image] 启动时,输出为:
  Hello world
  而如果通过 docker run -it [image] CloudMan 启动,则输出为:
  Hello CloudMan
  Shell 格式
  ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。
  最佳实践

  •   使用 RUN 指令安装应用和软件包,构建镜像。
  •   如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
  •   如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。
  到这里,我们已经具备编写 Dockerfile 的能力了。如果大家还觉得没把握,推荐一个快速掌握 Dockerfile 的方法:去 Docker Hub 上参考那些官方镜像的 Dockerfile

好了,我们已经学习完如何创建自己的 image,下一节讨论如何分发 image。
DSC0000.jpg

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-420889-1-1.html 上篇帖子: 配置docker官方源并用yum安装docker 下篇帖子: Docker 搭建开发环境
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表