您的位置:首页 >聚焦 >

环球滚动:Dockerfile之CMD、ENTRYPOINT指令

2022-08-03 22:37:46    来源:程序员客栈

这里对Dockerfile中的CMD、ENTRYPOINT指令进行介绍

abstract.png
CMD指令

该指令可以用于指定容器被启动时需要运行的命令。具体地,其支持shell、exec两种形式的语法

#shell格式CMDcommandparam1param2#exec格式CMD["command","param1","param1"]


(资料图片仅供参考)

通常Docker中推荐使用exec格式语法,原因有二。一方面,shell格式语法下会通过/bin/sh -c来执行命令;另一方面,某些镜像甚至不包含Shell,致使shell格式下的命令无法被正常执行。但使用exec格式时,会无法获取环境变量的值。此时则可以考虑使用shell格式语法

shell格式

下面通过Dockerfile定义一个名为demo1:test的镜像

#镜像demo1:testFROMbusybox:1.35.0#使用shell格式的CMDCMDpingbaidu.com

然后我们创建一个容器

dockerrun--namedemo1A--rm-itdemo1:test

如下所示,其会使用CMD指令设置的命令、参数执行

figure 1.jpeg

对于CMD指定的命令而言,不可以通过 docker run命令行实现传递参数。因为 CMD指令的命令、参数 会被 docker run命令行参数中指定的命令、参数 完全覆盖。例如我们创建一个容器,期望执行 ping weibo.com。则需要重新传递命令、参数

#错误方式:dockerrun--namedemo1B--rm-itdemo1:testweibo.com#正确方式dockerrun--namedemo1B--rm-itdemo1:testpingweibo.com

效果如下所示

figure 2.jpeg

又比如按下述方式创建命令,同理

dockerrun--namedemo1C--rm-itdemo1:testtop-H

效果如下所示

figure 3.png
exec格式

下面通过Dockerfile定义一个名为demo2:test的镜像

#镜像demo2:testFROMbusybox:1.35.0#使用exec格式的CMDCMD["ping","baidu.com"]

然后我们创建一个容器

dockerrun--namedemo2A--rm-itdemo2:test

如下所示,其会使用CMD指令设置的命令、参数执行

figure 4.jpeg

对于CMD指定的命令而言,不可以通过 docker run命令行实现传递参数。因为 CMD指令的命令、参数 会被 docker run命令行参数中指定的命令、参数 完全覆盖。例如我们创建一个容器,期望执行 ping weibo.com。则需要重新传递命令、参数

#错误方式dockerrun--namedemo2B--rm-itdemo2:testweibo.com#正确方式dockerrun--namedemo2B--rm-itdemo2:testpingweibo.com

效果如下所示

figure 5.jpeg

又比如按下述方式创建命令,同理

dockerrun--namedemo2C--rm-itdemo2:testtop-H

效果如下所示

figure 6.jpeg
ENTRYPOINT指令

该指令同样可以用于指定容器被启动时需要运行的命令。同理,其同样支持shell、exec两种形式的语法

#shell格式ENTRYPOINTcommandparam1param2#exec格式ENTRYPOINT["command","param1","param1"]

对于ENTRYPOINT指令而言,Docker中同样推荐使用exec格式语法,理由与CMD指令同理

shell格式

下面通过Dockerfile定义一个名为demo3:test的镜像

#镜像demo3:testFROMbusybox:1.35.0#使用shell格式的ENTRYPOINTENTRYPOINTtop-b

然后我们创建一个容器

dockerrun--namedemo3A--rm-itdemo3:test

如下所示,其会使用ENTRYPOINT指令设置的命令、参数执行

figure 7.jpeg

ENTRYPOINT指令 所设置命令、参数可被 docker run命令行参数中指定要运行的命令 覆盖, 但需要使用 --entrypoint 选项进行显式覆盖。否则将会忽略命令行参数

#错误方式dockerrun--namedemo3B--rm-itdemo3:testifconfig#正确方式dockerrun--namedemo3C--rm-it--entrypointifconfigdemo3:test

效果如下所示

figure 8.jpeg

当我们使用 --entrypoint 选项进行显式覆盖命令时,还可以传递参数

dockerrun--namedemo3D--rm-it--entrypointpingdemo3:testbing.com.cn

效果如下所示

figure 9.jpeg

对于shell格式的ENTRYPOINT指令设置的命令而言,如果没有使用--entrypoint 选项。当通过 docker run命令行传递参数时, 其会被忽略

dockerrun--namedemo3E--rm-itdemo3:test-H-m

效果如下所示

figure 10.jpeg
exec格式

下面通过Dockerfile定义一个名为demo4:test的镜像

#镜像demo4:testFROMbusybox:1.35.0#使用exec格式的ENTRYPOINTENTRYPOINT["top","-b"]

然后我们创建一个容器

dockerrun--namedemo4A--rm-itdemo4:test

如下所示,其会使用ENTRYPOINT指令设置的命令、参数执行

figure 11.jpeg

ENTRYPOINT指令 所设置命令、参数可被 docker run命令行参数中指定要运行的命令 覆盖, 但需要使用 --entrypoint 选项进行显式覆盖。否则将会忽略命令行参数

#错误方式dockerrun--namedemo4Bdemo4:testifconfig#正确方式dockerrun--namedemo4C--rm-it--entrypointifconfigdemo4:test

效果如下所示

figure 12.jpeg

当我们使用 --entrypoint 选项进行显式覆盖命令时,还可以传递参数

dockerrun--namedemo4D--rm-it--entrypointpingdemo4:testweibo.com

效果如下所示

figure 13.jpeg

对于exec格式的ENTRYPOINT指令设置的命令而言,如果没有使用--entrypoint 选项。当通过 docker run命令行实现传递参数时, 其会被追加

dockerrun--namedemo4E--rm-itdemo4:test-H-m

效果如下所示

figure 14.jpeg
组合使用

对于大多数场景下,CMD、ENTRYPOINT指令都是互相通用的,而且一般也会只使用其中一种指令。具体地,CMD指令方便镜像使用者更改容器运行的命令,故适用于较为灵活的场景;而如果不期望镜像使用者去轻易更改容器运行的命令,故推荐使用ENTRYPOINT指令。同时如前文所述,exec格式较shell格式更为推荐。而对于CMD、ENTRYPOINT指令二者组合使用时,其效果可参考下图

figure 15.jpeg

事实上对于组合使用二者来说,更为常见的一种实践方式是通过exec格式的ENTRYPOINT设置固定的命令、参数,而利用exec格式的CMD 设置默认的可变参数

下面通过Dockerfile定义一个名为demo5:test的镜像

#镜像demo5:testFROMbusybox:1.35.0#使用exec格式的ENTRYPOINT设置固定的命令、参数ENTRYPOINT["top","-b"]#使用exec格式的CMD设置默认的可变参数CMD["-H"]

然后我们创建一个容器

dockerrun--namedemo5A--rm-itdemo5:test

效果如下所示

figure 16.jpeg

由于此场景下CMD指令提供的是一个默认的可变参数,故我们可以通过docker run命令行参数 来覆盖 CMD指定的默认可变参数

dockerrun--namedemo5B--rm-itdemo5:test-m

效果如下所示

figure 17.jpeg

同理,ENTRYPOINT指令 所设置命令、参数可被 docker run命令行参数中指定要运行的命令 覆盖, 使用 --entrypoint 选项进行显式覆盖即可。当然此时CMD指令设置的默认可变参数也将失效

dockerrun--namedemo5C--rm-it--entrypointifconfigdemo5:test

效果如下所示

figure 18.jpeg

当然使用 --entrypoint 选项进行显式覆盖命令时,依然可以传递参数

dockerrun--namedemo5D--rm-it--entrypointpingdemo5:testweibo.com

效果如下所示

figure 19.jpeg
参考文献第一本Docker书·修订版 James Turnbull著深入浅出Docker Nigel Poulton著

关键词: 命令行参数 可变参数

相关阅读