一:docker run参数覆盖Dockerfile中CMD命令情况

首先要明确docker run指令中的参数是什么?

答案:docker run 指令(-it/-p/-d等) 镜像名 参数(/bin/sh、bash等),即docker run命令中,镜像名后面的 都是给容器执行的命令参数

举例说明docker run参数覆盖Dockerfile中CMD命令的情况:

首先基于镜像创建一个新的镜像,Dockerfile书写如下:

按道理说:用docker run执行使用镜像创建容器时,屏幕上应该会输出:Hello World。

接下来创建镜像:

镜像创建,承建了一个名为test,版本号(tag)为1的镜像

 

然后我们分别用docker run -it test:1 和 docker run -it test:1  bash  两个指令来使用镜像创建启动容器,注意观察他们的区别

一:docker run -it test:1

这里成功输出了Hello World

二:docker run -it test:1  bash

发现并没有输出Hello World, 而是执行了 bash指令给我们提供了交互界面,因此 是docker run -it test  bash中的bash命令参数覆盖了CMD。

关于CMD和ENTRYPOINT还有一点需要特别注意的是:如果一个Dockerfile中有多个CMD或ENTRYPOINT,只有最后一个会生效,前面其他的都会被覆盖

二:CMD与ENTRYPOINT区别

区别一:ENTRYPOINT不会被docker run 中的参数命令覆盖

区别二:如果在Dockerfile中CMD与ENTRYPOINT都存在,则CMD中的指令将会被作为ENTRYPOINT中的参数,即这时候CMD里的指令会失去它的作用,只是作为一个参数(可以理解为就是字符串)了,而且这个时候docker run后的参数指令依然会覆盖CMD,但是也会失去他本身的作用,仅仅是作为参数(字符串)提供给ENTRYPOINT中的命令

例如:一个Dockerfile文件内容如下:

FROM xxx(初始镜像名)

ENTRYPOINT ["echo"]

CMD ["Hello World"]

使用该Dockerfile创建新镜像后,执行 docker run -it 镜像名,就应该会输出:Hello World(没有实际操作验证)

接下来留一个小思考,如果使用该Dockerfile创建完成新镜像之后,执行docker run -it 镜像名 bash指令创建执行容器,CMD ["Hello World"] 这一条会不会被覆盖,会不会显示Hello World?

 

依然会覆盖CMD,因此不会输出Hello World 而是会输出bash,而且 现在的bash已经不是给我们提供交互界面的指令了,而是ENTRYPOINT中 echo的一个参数了,因此也无法给我们提供交互界面

 

从 docker ps -a就可以看出,使用镜像创建运行容器时执行的指令不是bash而是“echo bash“

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐