推荐阅读

Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506
Helm3(K8S 资源对象管理工具)博客专栏:https://blog.csdn.net/xzk9381/category_10895812.html

本文原文链接:https://blog.csdn.net/xzk9381/article/details/114635083,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

在编写 Dockerfile 过程中,需要使用 CMD 或 ENTRYPOINT 来指定容器运行时的命令。单从功能上来看,这两个命令的功能几乎是重复的,一般情况下使用其中一个命令就可以满足大部分的需求。接下来说一下 CMD 和 ENTRYPOINT 的不同点。

一、exec 和 shell 模式

首先要明确的一点就是 CMD 和 ENTRYPOINT 指令都可以使用 exec 和 shell 模式。这两种模式主要是用来指定容器中的不同进程作为 1 号进程。

1. exec 模式

前面提到了,exec 和 shell 模式会指定不同的进程作为容器内的 1 号进程。使用 exec 模式时,Dockerfile 中指定的命令就是容器内的 1 号进程,例如:

FROM ubuntu
CMD ["top"]

使用该 Dockerfile 构建镜像并运行,进入到容器内部使用 ps 命令可以发现 1 号进程就是 top 命令。

由于 exec 模式不会通过 shell 执行指令,所以使用该模式时无法获取到环境变量:

FROM ubuntu
CMD ["echo","${HOSTNAME}"]

构建镜像并运行后,可以发现在日志输出中的内容还是 ${HOSTNAME},并没有转换为对应的值。

但是如果使用 exec 模式执行 shell 就可以获得环境变量了:

FROM ubuntu
CMD ["/bin/bash","-c","echo ${HOSTNAME}"]

需要注意的是,使用 exec 模式需要使用双引号将参数包裹。

2. shell 模式

使用 shell 模式时,docker 会以 /bin/sh -c “task command” 的方式执行任务命令。也就是说容器中的 1 号进程不是任务进程而是 bash 进程:

FROM ubuntu
CMD top

构建镜像并运行后,使用 ps 命令可以发现 1 号进程是 /bin/sh -c top。

二、CMD 命令

CMD 命令用于为容器提供默认的启动命令。该命令有三种使用方式,其中最常用的一种是为 ENTRYPOINT 提供默认的参数,另外两种则是上面提到的 shell 和 exec 模式:

CMD ['param1','param2']

需要注意的是,在使用 docker run 命令时,如果手动指定了启动的命令,那么该命令会覆盖 Dockerfile 中的 CMD 指令。而且通过命令行指定的参数并不会传递到 CMD 命令中。

三、ENTRYPOINT 命令

ENTRYPOINT 命令同样用于为容器提供默认的启动命令。该命令有两种使用方式,也就是前面提到的 shell 模式和 exec 模式。基本用法是和 CMD 命令一样的,但是它也包含了一些特殊用法。

1. 示例一:指定 ENTRYPOINT 使用 exec 模式时,命令行上指定的参数会作为添加到 ENTRYPOINT 指定命令的参数列表中

FROM ubuntu
ENTRYPOINT ["top","-b"]

制作镜像后,使用如下命令启动容器:

docker run --rm test:v1 -c

进入容器中查看 1 号进程,可以发现进程为 top -b -c,这就说明命令行中的参数被添加到参数列表中了。

2. 示例二:使用 CMD 命令指定默认的参数列表

FROM ubuntu
ENTRYPOINT ["top","-b"]
CMD ["-c"]

制作镜像后,使用如下命令启动容器(不带有命令行参数):

docker run --rm test:v1

进入容器中查看 1 号进程,可以发现进程为 top -b -c。如果在启动容器时指定了参数:

docker run --rm test:v1 -n 1

那么 -n 1 参数会覆盖 CMD 中的参数,容器中实际执行的命令为 top -b -n 1

3. 示例三:指定 ENTRYPOINT 使用 shell 模式时,会完全忽略命令行参数

FROM ubuntu
ENTRYPOINT echo ${HOSTNAME}

制作镜像后,使用如下命令启动容器:

docker run --rm test:v1 ls

可以发现输出的内容是主机名称,而不是 ls 命令执行的结果。

4. 示例四:覆盖默认的 ENTRYPOINT 命令

在启动容器时,显示地指定 --entrypoint 参数可以覆盖默认的 ENTRYPOINT 命令:

docker run --rm test:v1 --entrypoint echo ${HOME}

四、了解 CMD 和 ENTRYPOINT 如何搭配使用

关于 CMD 和 ENTRYPOINT 如何搭配使用,官网给出了如下说明:

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  2. ENTRYPOINT should be defined when using the container as an executable.
  3. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
  4. CMD will be overridden when running the container with alternative arguments.

The table below shows what command is executed for different ENTRYPOINT / CMD combinations:

No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”]
No CMD error, not allowed /bin/sh -c exec_entry p1_entry exec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

总结起来的话,就是如下几点:

  1. 如果 ENTRYPOINT 使用了 shell 模式,CMD 指令会被忽略。
  2. 如果 ENTRYPOINT 使用了 exec 模式,CMD 指定的内容被追加为 ENTRYPOINT 指定命令的参数。
  3. 如果 ENTRYPOINT 使用了 exec 模式,CMD 也应该使用 exec 模式。

本文原文链接:https://blog.csdn.net/xzk9381/article/details/114635083,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

Dockerfile 中的 CMD 和 ENTRYPOINT 有什么区别相关推荐

  1. Dockerfile中的CMD和ENTRYPOINT有什么区别?

    本文翻译自:What is the difference between CMD and ENTRYPOINT in a Dockerfile? In Dockerfiles there are tw ...

  2. Dockerfile脚本:CMD与ENTRYPOINT的区别

    CMD & ENTRYPOINT ENTRYPOINT使用 FROM centos RUM yum install -y curl #ENTRYPOINT ["curl", ...

  3. Dockerfile CMD和ENTRYPOINT

    Dockerfile中的CMD和ENTRYPOINT 首先CMD和ENTRYPOINT这两个指令都是用来指定容器启动时运行的命令. 单从功能上来看,这两个命令几乎是重复的.单独使用其中的一个就可以实现 ...

  4. Docker配置Dockerfile中关键ENTRYPOINT和CMD命令详解

    一.dockerfile中的 CMD 1.每个dockerfile中只能有一个CMD如果有多个那么只执行最后一个. 2.CMD 相当于启动docker时候后面添加的参数看,举个简单例子: docker ...

  5. Dockerfile中CMD和ENTRYPOINT命令详解

    原文:https://m.jb51.net/article/136264.htm Dockerfile中CMD和ENTRYPOINT命令详解 发布时间:2018-03-12 11:46:00 作者:s ...

  6. Dockerfile中CMD和ENTRYPOINT区别

    CMD指令和ENTRYPOINT指令的作用都是为镜像指定容器启动后的命令,那么它们两者之间有什么各自的优点呢? 为了更好地对比CMD指令和ENTRYPOINT指令的差异,我们这里再列一下这两个指令的说 ...

  7. Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较

    1.概述 创建Docker镜像的方式有三种 docker commit命令:由容器生成镜像: Dockerfile文件+docker build命令: 从本地文件系统导入:OpenVZ的模板. 关于这 ...

  8. Dockerfile 中 CMD 写法的区别

    CSDN 中文章不一定能及时更新,欢迎点击前往我的博客查看最新版本:许盛的博客 Dockerfile 中的 CMD 是个非常重要的指令,主要用于为容器提供启动命令,但是写法上有好几种方式,一段时间不看 ...

  9. Dockerfile 的 CMD 与 ENTRYPOINT 傻傻分不清楚

    CMD 和 ENTRYPOINT 指令都是用来指定容器启动时运行的命令. 单从功能上来看,这两个命令几乎是重复的.单独使用其中的一个就可以实现绝大多数的用例.但是既然 doker 同时提供了它们,为了 ...

最新文章

  1. 超越AlphaZero,DeepMind新算法MuZero登顶Nature | AI日报
  2. JavaWeb_域对象的属性操作
  3. HTTP报文简单介绍
  4. rpython求随机数代码4段5个字符_如何创建一个4位数的随机数并将其存储为变量...
  5. 钢铁苍穹html5,自定义网站搜索教程
  6. Citrix桌面及应用虚拟化系列之二:XenServer补丁
  7. 【ElasticSearch】Es 源码之 MetadataUpgrader 源码解读
  8. python菜鸟教程网-Python JSON
  9. php解密 hr+c_PHP每15分钟自动更新网站地图(减少服务器消耗)
  10. SLAM++:面向对象的同时定位与建图系统(2013-CVPR)
  11. 占空比输出程序c语言,怎样利用c语言来实现占空比的设置?(单片机:SPCE061A)
  12. Microsoft SQL Server 2008 (RTM) 升级到 Microsoft SQL Server 2008 R2
  13. 分布式服务框架 HSF
  14. 计算机学报应用研究,组推荐系统及其应用研究-计算机学报.PDF
  15. 命令行方式实现QQ自动登录
  16. html如何做动态桌面壁纸,wallpaper engine怎么自己做壁纸?动态壁纸制作方法
  17. 十招挑出皮薄味甜的西瓜
  18. google海底光缆图_SubmarineCableMap:世界海底光缆分布图
  19. OpenWRT系统(二) - LoRa基站开发
  20. mysql主从同步怎么指定端口_MySQL主从同步配置

热门文章

  1. UVA10878 Decode the tape【编码】
  2. 电压、电流 —— 常用设备的电压电流
  3. 神经网络的 Delta 学习规则(learning rule)
  4. 学习算法收敛条件的判断
  5. Git 基础(十)—— 常用命令
  6. 机器学习基础(二十)—— 数学语言与 Python 代码
  7. 逻辑思维与C/C++解题
  8. python三本经典书籍-《python编程入门经典》python之父推荐这三本书让你更快入门...
  9. python3.7安装步骤-Python 3.7.0安装教程(附安装包) | 我爱分享网
  10. python从入门到精通-Python从入门到精通