Docker 中 RUN、CMD 与 ENTRYPOINT 的区别_docker run cmd-程序员宅基地

技术标签: 云原生  容器  运维  docker  

前言

在说 CMD、RUN 和 ENTRYPOINT 的区别前,先来说说 Dockerfile,Dockerfile 是构建容器镜像的方式之一,其通过一系列的指令参数来完成镜像的构建,而这些参数正是包含了 CMD,、RUN、COPY、ADD 和 ENTRYPOINT 等一系列指令。因此在实际应用中我们更多都是通过 Dockerfile 来完成镜像的构建。接下来列举一些 Dockerfile 常用的指令。

一、Dockerfile 常用指令

  • FROM

    指定基础(base)镜像,本地有镜像则直接使用,否则直接在线拉取(pull)。

  • MAINTAINER

    Author,对作者的简单描述,自定义。

  • COPY

    将文件或目录从 build context 复制到镜像,其支持两种格式:COPY src dest 和 COPY[“src”,“dest”]

    注:原目标(src)只能是文件或目录。

  • ADD

    与 COPY 类似,复制文件到镜像,不同的是,ADD 的 src 是归档文件(tar、zip、tgz 等),这些归档文件会被自动解压到 dest (镜像目标路径),无需手动解压。

  • ENV

    设置环境变量,该变量可被后面的指令使用。

  • EXPOSE

    指定容器中的进程会监听的某个端口,指定后 Docker 可以将该端口暴露出来。

  • VOLUME

    将文件或目录声明为 volume,同样 Docker 可以将该目录或文件映射出来。

  • WORKDIR

    为后面的 RUN、CMD、ENTRYPOINT、ADD、COPY 指令设置镜像中的当前工作目录。

  • RUN

    在容器中运行指令的命令。

  • CMD

    启动容器时运行指定的命令,Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,如果 docker run 后面指定有参数,该参数将会替换 CMD 的参数。

  • ENTRYPOINT

    同样,在 Dockerfile 中可以有多个 ENTRYPOINT 指令,也是只有最后一个生效,但与 CMD 不同的是,CMD 或 docker run 之后的参数会被当作参数传给 ENTRYPOINT。

二、三者的区别

2.1 Shell 和 Exec 格式

通常,我们有两种方式来指定 RUN、CMD 和 ENTRYPOINT 要运行的命令,即 Shell 和 Exec 方式。CMD 和 ENTRYPOINT 推荐使用 Exec 格式,其可读性更强。

1、Shell 格式

RUN yum install -y vim
CMD echo "hello zhurs"
ENTRYPOINT echo "hello zhurs"

# 运行容器时返回如下结果
hello zhurs

当指令执行时,Shell 格式会调用 /bin/sh -c [command]

2、Exec 格式

[“executable”, “param1”, “param2”]

RUN ["yum", "install", "-y", "vim"]
CMD ["bin/echo", "zhurs"]
ENV wd world
ENTRYPOINT ["/bin/echo", "hello, $wd"]

# 运行容器时返回如下结果
hello $wd

# 可看到运行容器时并没有调用/bin/sh -c 没有被shell解析(环境变量wd并没有被替换)。

# 如果希望使用环境变量,可做如下操作
RUN ["yum", "install", "-y", "vim"]
CMD ["bin/echo", "zhurs"]
ENV wd world
ENTRYPOINT ["bin/sh", "-c", "/bin/echo", "hello, $wd"]

# 此时就会返回如下结果
hello world

2.2 RUN

RUN 指令通常用于安装应用和软件包,每条 RUN 指令都会生成新的镜像。

...
RUN apt update && apt install -y git
...

像在安装一些基础工具或应用的时候,apt update 和 apt install … 最好放在一个 RUN 指令下执行,因为这能够保证每次安装的是最新的包,如果 apt update 在单独的 RUN 下运行,则 apt install … 会使用 apt update 创建的镜像,而这一层镜像可能是很久以前缓存的镜像文件。

2.3 CMD

该指令用于用户启动容器时,容器来执行的命令,该命令会在容器启动且 docker run 后面没有指定其他命令时执行,所以小结三种情况:

  • docker run 没指定其他命令:则启动容器时运行 CMD 后的命令;
  • docker run 指定了其他命令:则启动容器时运行 CMD 后的命令会被忽略;
  • Dockerfile 中有多条 CMD 指令时,仅最后一条生效。

CMD 的三种格式:

  • shell 格式:CMD <二进制可执行命令> <指令1> <指令2> 如:CMD yum install -y vim
  • exec 格式:CMD [“二进制可执行命令”, “指令1”, “指令2”] 如:RUN [“yum”, “install”, “-y”, “net-tools”]
  • CMD [“a”,“b”] 格式:该格式是为 ENTRYPOINT 提供使用,此时 ENTRYPOINT 就必须使用 exec 格式,否则不生效。

2.4 ENTRYPOINT

该指令可以让容器以应用程序或者服务的形式运行。与 CMD 不同的是,不管 docker run … 后是否运行有其他命令,ENTRYPOINT 指令后的命令一定会被执行。

ENTRYPOINT 的两种格式:

  • shell 格式:同 CMD;
  • exec 格式:同 CMD。

ENTRYPOINT 的 exec 格式可以可执行由 CMD 提供的额外参数,具体如下:

...
ENTRYPOINT ["/bin/echo", "hello"] CMD ["world"]
...

运行容器时:

  • docker run -it

    运行的容器后无任何参数

    # 输出
    hello world
    
  • docker run -it myworld

    运行的容器后跟了 myworld 参数

    # 输出
    hello myworld
    

ENTRYPOINT 小结:

无论运行的容器命令后是否有其他参数,ENTRYPOINT 一律执行,如果 ENTRYPOINT 后跟随有 CMD 指令参数,则该参数的内容将会作为 ENTRYPOINT 指令参数。如果 docker run ... 后有参数,ENTRYPOINT 则使用该参数,而不会使用 CMD 的参数,为什么呢?因为 docker run ... 后指定了参数,那么根据前面说到的 CMD 后的参数将会被忽略掉(或叫被替换)。

但是上面的结论是针对 ENTRYPOINT 的 exec 格式而言的,如果是 shell 格式,ENTRYPOINT 将会忽略掉任何 CMD 或 docker run … 提供的参数。当然 ENTRYPOINT 的 shell 格式也是会必然执行的。

2.5 如何选择 CMD 和 ENTRYPOINT

根运行容器的属性来合理选择

  • 如果运行的是一个 MySQL 容器,则优先使用 exec 格式的 ENTRYPOINT 指令,因为 CMD 不仅可以为 ENTRYPOINT 提供默认参数,同时在 docker run ...(带参数)的时候,该参数也会替换 CMD 默认参数。
  • 如果只是简单的设置容器默认的启动命令,使用 CMD 即可,用户只需在 docker run ... 后添加参数即可替换默认值。

小结

  • RUN:执行命令并创建新的镜像层,常用于安装软件包;
  • CMD:设置容器启动后默认执行的命令及其参数,但 docker run 后跟参数时会替换(忽略) CMD;
  • ENTRYPOINT:配置容器启动时运行的命令。

<点击跳转至开头>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/IT_ZRS/article/details/124707747

智能推荐

windows环境下JSP环境搭建:Apache2(1)-程序员宅基地

文章浏览阅读307次,点赞2次,收藏3次。在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。

Android:利用Java反射调用@hide的API_connectivitymanager 反射-程序员宅基地

文章浏览阅读1.6w次,点赞4次,收藏13次。设置使用3G数据功能:从源代码看到隐藏的API(ConnectivityManager.java): /** * Sets the persisted value for enabling/disabling Mobile data. * * @param enabled Whether the mobile data connection should_connectivitymanager 反射

[渝粤教育] 中国地质大学 互换性与测量技术 复习题 (2)_要求两孔同轴度φ0.3mm最大偏差是多少-程序员宅基地

文章浏览阅读941次。《互换性与测量技术》模拟题一.单选题1.优先选用基孔制的原因是().A.孔比轴难加工B.减少定尺寸孔用刀具量具的规格和数量C.减少孔和轴的公差带数量D.从工艺上讲应先加工孔后加工轴2.评定齿轮传递运动准确性的指标是().A.齿距累积总偏差B.单个齿距偏差C.齿廓总偏差D.螺旋线总偏差3.当几何公差框格的指引线箭头与尺寸线对齐时所表示的被测要素是().A.轮廓要素B.单一要素C.中心要素D.基准要素4.螺纹代号M20×2-7g6g表示的螺纹是().A.粗牙普通外螺纹B.粗_要求两孔同轴度φ0.3mm最大偏差是多少

Simulink模型转为TwinCAT3可以运行的ST程序_simulink导入到twincat-程序员宅基地

文章浏览阅读1k次。@Simulink PLC Coder :将Simulink模型转为TwunCAT程序1 先把simulink程序封装为一个子系统subsystem,标注好输入输出端口参考链接:https://ww2.mathworks.cn/help/plccoder/ug/plc-coder-general.html#bsemuq2-12 程序内不能包含任何连续状态的模块(比如微分,积分模块),而且有不支持的等simulink模块(比如Clock模块),因此需要用离散状态的功能块替代,或者编写MATLAB _simulink导入到twincat

程序员35岁真的是分水岭吗?复习指南_程序员35岁为什么会是一个分水岭-程序员宅基地

文章浏览阅读100次。缘起随着互联网企业的不断发展,产品项目中的模块越来越多,用户体验要求也越来越高,想实现小步快跑、快速迭代的目的越来越难,还有应用之间的互相调用等等问题,插件化技术应用而生。如果没有插件化技术,美团、淘宝这些集成了大量“app”的应用,可能会有几个g那么大。所以,当今的Android移动开发,不会热修复、插件化、组件化,80%以上的面试都过不了。阿里P8大佬每天熬夜到凌晨一两点,花了将近半个月时间将Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、_程序员35岁为什么会是一个分水岭

echarts全国地图点击弹窗(Vue)_echarts地图点击弹出窗体明细-程序员宅基地

文章浏览阅读5k次,点赞2次,收藏18次。实现echart 全国地图点击标记有弹窗_echarts地图点击弹出窗体明细

随便推点

Win10解决Disciples 2圣战群英传2卡顿问题_disciples 2如何窗口化运行-程序员宅基地

文章浏览阅读5.9k次。最近想翻点老游戏出来玩,比如圣战群英传2,但是卡得我mmp,一通搜索和捣鼓之后,终于发现了比较简单的解决问题的方法。1、首先确认电脑中是否有vcredist2010,至少08年以后的VC++库,没有就安。2、检查游戏根目录下有没有d3d9.dll,没有就下方传送门。https://dl.pconline.com.cn/download/91252.html如果还没能解决问题,那么:3、看看根目录有没有Disciple.ini,如果没有:3.1、看看根目录有没有一个骷髅头头像的Importer.e_disciples 2如何窗口化运行

数据链路层循环冗余(CRC)检验_链路层循环冗余校验码是检验哪一部分-程序员宅基地

文章浏览阅读5.5k次。数据链路层有许多协议,但有三个基本问题是相同的:封装成帧、透明传输和差错检验。为了保证数据传输的可靠性,在计算机网络传输数据时,必须采用各种差错检验措施,目前广泛使用的是循环冗余(CRC)检验的检错技术。 CRC检验原理: 在发送端,先把数据划分为组,假定每个组k个比特。现假定待传送的数据M=101001(k=6)。CRC运算就是在数据M后面添加供差错检验用的n位冗余码,然后构成一个帧发送出去,_链路层循环冗余校验码是检验哪一部分

Spring Security(08)——intercept-url配置_intercept-url j_spring_security_logout-程序员宅基地

文章浏览阅读1w次。Spring Security介绍系列文章。本文主要介绍如何通过intercept-url配置来实现对特定的URL进行拦截,包括指定访问权限、指定访问协议、指定请求方法_intercept-url j_spring_security_logout

iserdese2接口详解_Xilinx 7系列FPGA之SelectIO(3)——高级IO逻辑资源简介-程序员宅基地

文章浏览阅读1.7k次。上一篇咱们介绍了IO逻辑资源,本篇咱们来聊一聊高级的IO逻辑资源,即ISERDESE2模块和OSERDESE2模块。所谓ISERDESE2模块,即Input serial-to-parallel converters。该模块的作用就是实现高速源同步输入数据的串并转换。所谓OSERDESE2模块,即output parallel-to-serial converters。该模块的作用就是实现高速源同..._iserdese2用法

服务没有注册到nacos的原因分析_服务注册不到nacos-程序员宅基地

文章浏览阅读6.9k次,点赞9次,收藏4次。服务没有注册到nacos的原因分析因为没有加上版本号,导致不能注册。 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>0.2.1.RELEASE<_服务注册不到nacos

Android应用去掉标题栏状态栏(Android Studio)_android studio 应用禁用状态栏-程序员宅基地

文章浏览阅读442次。**网上关于Android Studio的教程比较少,去掉标题栏的方法大多不能直接使用。 在Android Studio中其实更简单一些,在app/res/values/styles.xml文件中加个标签就可以了**true 完整代码如下,可以看到这段代码放在什么位置。

推荐文章

热门文章

相关标签