CMD 命令和 ENTRYPOINT 命令的区别

2023-11-03

CMD 命令

CMD-shell 形式

1. 创建 Dockerfile1

vim Dockerfile1
# 写入以下两行内容
FROM centos:7
CMD cal

2. 构建和运行新镜像

# 说明:-f 用于指定本次构建所要使用的Dockerfile的文件名。
docker build -f Dockerfile1 -t my-cal:1.0 .

构建成功运行新镜像。运行后可以查看到当前月份的日历。

image-20230911102224504

3. 覆盖 CMD

image-20230911100132103

在 docker run 命令中指定要执行的命令,Dockerfile 中通过 CMD 指定的默认的命令就不会在执行,也就是说Dockerfile 中的 CMD 命令是可以被覆盖的。

4. 添加命令选项

image-20230911102303525

cal命令添加 -y 选项可以显示当前年的所有月份。但这种方式无法为 CMD 中指定的默认的命令指定选项。

小总结

cmd-shell的形式可以被覆盖,但不能添加命令选项。

CMD-exec形式

1. 创建Dockerfile2、构建和运行新镜像

此步骤与前面类似,只是把Dockerfile1里面的CMD cal 替换为CMD [“cal”] 或者CMD [“/bin/bash”, “-c”, “cal”]。

CMD-exec形式的语法:

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

  • “executable” 是你想要运行的命令或程序。
  • “param1”,“param2” 是传递给这个命令或程序的参数。

image-20230911102606406

image-20230911102631745

最后运行新镜像的结果和CMD-shell 形式的结果一样。

2.覆盖 CMD和添加命令选项

image-20230911102701172

小总结

cmd-exec的形式可以被覆盖,但不能添加命令选项。

ENTRYPOINT 命令

ENTRYPOINT-shell

1. 创建Dockerfile3、构建和运行新镜像

ENTRYPOINT-shell形式的语法:ENTRYPOINT command param1 param2

vim Dockerfile3
# 写入以下两行内容
FROM centos:7
ENTRYPOINT cal
# 构建镜像
docker build -f Dockerfile3 -t my-cal:3.0 .
# 运行镜像
docker run -it my-cal:3.0

结果如下:

image-20230911152434533

2. 覆盖 ENTRYPOINT 和 添加命令选项

image-20230911152648861

可以看到ENTRYPOINT-shell形式的指令是不会被 docker run 中指定的命令给覆盖掉的。在 docker run 中添加的命令选项,对于 ENTRYPOINT 中指定的命令是无效的。在这点上不像 CMD 指令一样报错。

ENTRYPOINT-exec

为了更好的理解ENTRYPOINT命令,ENTRYPOINT-exec又分了两种情况进行讨论。分别是ENTRYPOINT [“cal”] 和 ENTRYPOINT [“/bin/bash”,“-c”,“cal”] 。看看它们之间的区别有哪些以及为什么。

1. 创建Dockerfile4、构建和运行新镜像

vim Dockerfile4
# 写入以下两行内容
FROM centos:7
ENTRYPOINT ["cal"]
# 构建镜像
docker build -f Dockerfile4 -t my-cal:4.0 .
# 运行镜像
docker run -it my-cal:4.0

运行结果如下:

image-20230911153728227

2. 覆盖 ENTRYPOINT 和 添加命令选项

image-20230911153851075

可以看到这种的ENTRYPOINT-exec形式的指令也是不会被 docker run 中指定的命令给覆盖掉的,并且会报出错误信息。而在 docker run 中添加的命令选项,对于 ENTRYPOINT 中指定的命令却是是有效的,能够显示出整年的日历。

ENTRYPOINT-exec 的另一种写法

为了节省篇幅,我简要写出关键步骤后直接看运行结果。

# 建立Dockerfile5
vim Dockerfile5
# 写入以下两行内容
FROM centos:7
ENTRYPOINT ["/bin/bash","-c","cal"]
# 构建镜像
docker build -f Dockerfile5 -t my-cal:5.0 .
# 运行镜像
docker run -it my-cal:5.0

运行结果如下:

image-20230911154657701

覆盖 ENTRYPOINT 和 添加命令选项的结果如下:

image-20230911154753592

发现最后的结果与ENTRYPOINT-shell的形式一样。也就是不会被覆盖并且添加选项无效。

基于前面五个实验的总结

Dockerfile的命令 命令是否可以被覆盖 是否可以添加选项
CMD cal 可以被覆盖 不能添加选项,添加选项后会报错
CMD [“cal”] 可以被覆盖 不能添加选项,添加选项后会报错
ENTRYPOINT cal 不可以被覆盖,添加的命令会被忽略 不能添加选项,添加的选项被忽略
ENTRYPOINT [“cal”] 不可以被覆盖,添加命令后会报错 可以添加选项
ENTRYPOINT [“/bin/bash”,“-c”,“cal”] 不可以被覆盖,添加的命令会被忽略 不能添加选项,添加的选项被忽略

在总结之前先来看看docker run命令的语法:

image-20230911161656508

可以看到:IMAGE的后面是可以接命令和参数的,但命令和参数并不是必须的,所以用 [ ] 括起来了。所以结论如下:

  1. shell命令格式和exec命令格式的区别:

    对于 shell 形式的 ENTRYPOINT 或者 CMD,docker daemon 会创建一个新的 /bin/bash shell 进程,并在这个新进程中运行你的命令。这意味着你的命令会在一个新的 shell 环境中运行,这个环境有它自己的环境变量,且和启动容器的环境是隔离的。

    这与 exec 形式不同,exec 形式直接在 Docker 容器的主进程中运行命令,没有额外创建 shell 进程。这就是为什么 exec 形式可以接收 docker run 附加的参数。

  2. CMD指令:

    Dockerfile 中的 CMD 指令是可以被docker run 命令中的[COMMAND]替代的。也就是说,如果docker run命令中的 IMAGE 后仍有内容,此时docker daemon 首先会将IMAGE后面的[COMMAND]替换掉CMD指令中的[COMMAND],如果有两个或两个以上的内容,docker daemon会认为是从第二个内容开始后面的都是[ARG]。所以,添加的-y 会报错,这是因为没有-y 这样的[COMMAND]。

  3. ENTRYPOINT指令:

    如果Dockerfile中的[EXECUTABLE]是通过 ENTRYPOINT 指定的,则该镜像的启动命令 docker run 中是可以添加参数[ARG]的。也就是说,ENTRYPOINT指定的命令是不可被替代的,并且如果IMAGE后面还有内容,这些内容会被作为参数传递给ENTRYPOINT指定的命令。但加上参数后如果有语法错误,那么docker daemon就会忽略该参数。

最后的总结:基于以上三个结论,下面我就写一下每种命令执行的底层原理。

  1. 对于CMD-shell来说,首先docker daemon会fork一个新进程,该进程就是一个shell环境。如果docker run 命令后面的IMAGE没有命令和参数,那么docker daemon会将Dockerfile里面的CMD-shell命令放在这个新shell里面执行;如果docker run 命令后面的IMAGE有命令和参数,那么会将IMAGE后面的命令和参数放在新shell里面执行。在这个新的 shell 环境有它自己的环境变量,且和启动容器的环境是隔离的。
  2. 对于CMD-exec来说,命令的执行环境就是运行容器的主进程的环境。如果docker run 命令后面的IMAGE没有命令和参数,那么docker daemon会将Dockerfile里面的CMD-shell命令放在运行容器的主进程的环境执行;如果docker run 命令后面的IMAGE有命令和参数,那么IMAGE后面的命令和参数将会替换掉Dockerfile里面的CMD-exec命令,也就是只执行IMAGE后面的命令和参数
  3. 对于ENTRYPOINT-shell来说,首先docker daemon会fork一个新进程,该进程就是一个shell环境。如果docker run 命令后面的IMAGE没有命令和参数,那么docker daemon会将Dockerfile里面的 ENTRYPOINT-shell 命令放在这个新shell里面执行;如果docker run 命令后面的IMAGE有命令和参数,那对不起,IMAGE后面所有的命令和参数都会被丢弃
  4. 对于ENTRYPOINT-exec来说,命令的执行环境就是运行容器的主进程的环境。如果docker run 命令后面的IMAGE没有命令和参数,那么docker daemon会将Dockerfile里面的ENTRYPOINT-exec命令放在运行容器的主进程的环境执行;如果docker run 命令后面的IMAGE有命令和参数,那么docker daemon会将IMAGE后面所有的命令和参数追加到Dockerfile里面的ENTRYPOINT-exec命令的后面,但是如果追加后有语法错误,那么就不会追加了。最后在运行容器的主进程的环境执行命令
  5. 最后就是ENTRYPOINT [“/bin/bash”,“-c”,“cal”]的执行原理了,其实这有点类似于shell和exec两种形式的结合版,对于最后这个命令的底层执行原理请读者自行理解。不过需要注意的是cal -y的执行结果和/bin/bash -c cal -y的执行结果是不一样的;而 cal -y 和 /bin/bash -c “cal -y” 这两条命令的执行结果是一样的。

CMD 与 ENTRYPOINT 组合使用

这两个指令都用于指定容器启动时要执行的命令,无论哪个指令,每个 Dockerfile 中都只能有一个 CMD/ENTERYPOINT 指令,多个 CMD/ENTERYPOINT 指令只会执行最后一个。如果同时存在多个CMD 和 ENTRYPOINT,Docker 只会执行最后一个。此外,CMD 和 ENTRYPOINT 可以配合使用。当 ENTRYPOINT 和 CMD 同时存在时,CMD 中的内容会被作为 ENTRYPOINT 的参数。在这种模式下,docker run 命令后面的参数会覆盖 CMD 的内容。

验证如下:

# 新建Dockerfile6
vim Dockerfile6
# 写入以下三行内容
FROM centos:7
CMD ["hello world"]
ENTRYPOINT ["echo"]
# 构建镜像
docker build -f Dockerfile6 -t my-cal:6.0 .
# 运行镜像
docker run -it my-cal:6.0

运行结果如下:

image-20230911185712380

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMD 命令和 ENTRYPOINT 命令的区别 的相关文章

随机推荐

  • 数学建模竞赛常用代码总结-Python&Matlab

    数学建模过程中有许多可复用的基础代码 在此对 python 以及 MATLAB 中常用代码进行简单总结 该总结会进行实时更新 一 文件读取 python pandas 文件后缀名 扩展名 并不是必须的 其作用主要一方面是提示系统是用什么软件
  • G1垃圾收集分类-JVM(十四)

    上篇文章说了G1不在是连续的老年代年轻代 而是分为不同的region 有eden survivor old humongous 当大于百分之50region的数据则直接进入humongous 如果对象太大 会连续的存储 分为初始标记 并发标
  • 天津python爬虫培训

    许多许多同学都想开始学习Python 想做一位有着高薪的程序员 但是成为程序员也是有条件的 不是随随便便就能开始编程 哪怎么才能成为程序员呢 首先我们得先了解Python 知道一些基本知识 先入门 然后再开始一步一步的学习 慢慢地向程序员靠
  • 自动化测试框架理解

    自己总结的框架原理 虽然其中的含义还是比较模糊 但对于应付面试足够啦 数据驱动的测试方法 数据驱动从数据文件读取输入数据 通过变量的参数化将测试数据传入测试脚本 不同的数据文件对应不同的测试用例 我理解的就是不同的功能点测试 用一个表格列出
  • Python卸载

    Python卸载 因学习深度学习知识 需要安装Anaconda 而Anaconda本身会自带一个版本的python 为了不产生python版本之间的冲突 想要卸载原先安装的python 卸载python主要有以下几个步骤 1 找到安装pyt
  • java解析zip文件

    java解析zip文件 1 工具类 package org springblade iot utils import org apache commons fileupload FileItem import org apache comm
  • 数组 只出现一次的数字

    题目 只出现一次的数字 说明 给定一个非空整数数组 除了某个元素只出现一次以外 其余每个元素均出现两次 找出那个只出现了一次的元素 Swift 题目 只出现一次的数字 说明 给定一个非空整数数组 除了某个元素只出现一次以外 其余每个元素均出
  • React生命周期执行顺序详解

    文章内容转载于https www cnblogs com faith3 p 9216165 html 一 组件生命周期的执行次数是什么样子的 只执行一次 constructor componentWillMount componentDid
  • qemu: could not load PC BIOS 'bios-256k.bin'

    qemu kvm 创建虚拟机时报错了 qemu could not load PC BIOS bios 256k bin 我在指定了BIOS后仍然不对 使用 find bios 256k bin 我发现 bios 256k bin是一个软连
  • 【shell】-exec和xargs

    目录 实现效果 参数说明 exec参数 xargs参数 exec和xargs 后执行多条语句 exec和xargs 执行自定义函数 如何正确组合 xargs bash c 和环境变量 exec和xargs的区别 exec和xargs的区别
  • C++primer U10 读书笔记 关联容器

    pair 类型 pair
  • 当出现jquery”ScriptResourceMapping时

    在使用MVC框架的时候出现这个问题 jquery ScriptResourceMapping 有以下几个参考步骤 1 添加引用 管理NuGet程序包 在搜索框中搜索jquery 版本有更新 在右侧点击安装jqu 安装后显示script文件
  • unity2D备忘志

    一 角色移动 unity里面的transform组件非常好用 transform right这种枚举值真的很方便 Vector2向量 控制移动方向 Input输入非常非常方便 后面章节有刚体移动 应用也很广泛 transform Trans
  • 质数判断算法

    有人做过这样的验算 1 2 1 41 43 2 2 2 41 47 3 2 3 41 53 于是就可以有这样一个公式 设一正数为n 则n 2 n 41的值一定是一个质数 这个式子一直到n 39时 都是成立的 但n 40时 其式子就不成立了
  • threejs使用tweenjs实现点击标签过渡到相应视角

    效果图 1 点击前 2 点击后 说明 效果就是我在给模型打标签时保存视角和坐标 点击标签的时候读取到坐标数据 再转动到对应视角 1 安装 TWEEN npm install save tweenjs tween js 2 在当前页引入 im
  • springboot整合springcache (redis)

    1 引入依赖
  • 阿里巴巴的18位创始人

    1999年 阿里巴巴集团成立 当时共有18位创始人 大部分是马云的同事 朋友和学生 这篇文章汇总了这18个人的公开资料 马云是阿里巴巴的代言人 然而 事实上 自1999年成立以来 还有17位重要人物共同创立了这家电子商务巨头 但是他们是谁
  • 微信小程序 scroll-view 组件的 bindscroll 不触发不生效

    使用微信小程序基础组件中的scroll view 但是滑动的时候 bindscroll 一直不生效
  • 授人以渔command not found: ***

    配置环境变量是每个开发人员绕不开的初级本领 搜了一下大多数博客都是列出自己系统配置的步骤 授人以鱼不如授人以渔 今天记录一下自己配置验证的方法过程 方便初学者配置 本文围绕 我在macOS配置http server的探究验证过程 1 下载
  • CMD 命令和 ENTRYPOINT 命令的区别

    目录 CMD 命令 CMD shell 形式 1 创建 Dockerfile1 2 构建和运行新镜像 3 覆盖 CMD 4 添加命令选项 CMD exec形式 1 创建Dockerfile2 构建和运行新镜像 2 覆盖 CMD和添加命令选项