0


Dockerfile中的RUN、CMD、ENTRYPOINT的区别详解

我们在构建Docker镜像的时候,可以通过定义Dockerfile文件的方式,文件中包含了一系列命令参数,而这些参数正是包含了 CMD,、RUN、COPY、ADD 和 ENTRYPOINT 等一系列指令。这篇文章我们一起来学习下其中RUN、CMD、ENTRYPOINT三个命令参数的作用及区别。文章涉及到实际操作,截图多,篇幅长,可以直接跳转到最后看总结了解。

Shell 和 Exec命令格式

无论是RUN、CMD还是ENTRYPOINT运行的命令,都可以Shell或者Exec格式的,两者有一定的区别。总的来说,Shell格式的命令,在底层调用时,会在命令前加上

/bin/sh 

,那么命令中的用

$

修饰的参数会被替换;而Exec格式的命令,更像是字符串数组类型,如果自己没有添加

/bin 

,就不会进行参数替换。话不多说,看例子。

先创建一个空目录,目录中新建一个Dockerfile文件,文件内容如下:

FROM ubuntu:latest
ENV name Ultraman
RUN echo"RUN shell Hello $name!"#CMD echo "CMD shell Hello $name!"#ENTRYPOINT echo "ENTRYPOINT shell Hello $name!"#RUN ["echo","RUN exec Hello $name!"]#CMD ["echo","CMD exec Hello $name!"]#ENTRYPOINT ["echo", "ENTRYPOINT exec Hello $name!"]

注意这里

#

是注释,方便一条一条命令做演示调试。
Dockerfile

Shell

这里我们用RUN命令来做演示。接着我们根据此Dockerfile来构建镜像。

在这里插入图片描述

RUN命令其实是在构建镜像的时候会被执行,看图中框起来的部分可以看到RUN命令被正确执行,并且

name

参数也成功替换了。这是Shell方式,我们再来看看Exec方式。

Exec

在这里插入图片描述
修改Dockerfile文件,并且构建,可以看到构建过程中有打印,但是

name

变量没有被正确替换,如果想要使用Exec格式,需要修改下命令,例如:
在这里插入图片描述

RUN

我们在了解了两种命令格式之后,来看下三个命令的使用及区别。

RUN

命令是在构建镜像的时候被执行的,所以一般用来安装应用和软件包,一个Dockerfile中可以包含多个RUN命令来安装多个应用或者软件包。另外,我们知道Docker的镜像常常是由多个镜像层layer组成的,一个RUN命令就会在镜像的顶部可写层创建一个新的镜像层。

例如:

RUN yum update && yum install-y\  
 bzr \
 cvs

注意 通常我们把yun update 和 yum install 命令会放在一个RUN指令中一起执行,这样可以保证每次安装的包都是最新版本的。如果我们分开来执行,比如放在两个RUN命令中,那么我们无法保证每次下载的都是最新的包,因为一个RUN命令对于Docker来说会生成一个新的layer层,有可能在之前就已经创建过yum update的层,有缓存。这个在了解了Docker的原理之后会更好的理解。

CMD

CMD

命令设置容器启动后默认执行的命令及其参数,但CMD能够被docker run后面跟的命令行参数替换。例如:
我们在Dockerfile中加上一段

cmd echo "Hello world"

,然后docker build成镜像,并且执行

docker run -it <imagename>

启动一个容器,看到输出
在这里插入图片描述
我们这时候修改启动命令,在启动命令后面加上一个命令,可以看到CMD的内容被覆盖了
在这里插入图片描述
另外,需要注意的是,如果Dockerfile中有多个CMD,那么只会有最后一个生效,如果容器启动时没有指定要执行的命令,那么就会执行最后一个。
在这里插入图片描述

ENTRYPOINT

ENTYRYPOINT

命令也可以用来当作启动容器时执行的命令,与

CMD

不同的是,

ENTRYPOINT

命令始终会被使用,也不会轻易的被docker启动命令覆盖。可以使用docker run --entrypoint参数覆盖。
举个例子说明:

ENTRYPOINT ["/bin/sh"]
CMD ["-c","java $JAVA_OPTS -jar /demo.jar","--server.port=8000"]

很多官方的基础镜像的启动命令都是/bin/bash,容器启动就会进入终端命令行。

两种命令格式:
如果是ENTRYPOINT + [Exec]格式命令,那么CMD的参数会被追加在后面;
如果是ENTRYPOINT + shell格式命令,那么就会忽略CMD以及启动参数,当然此命令依然会被执行。

所以一般ENTRYPOINT用来当作Dockerfile的最后一行,CMD用于指定容器启动时要执行的命令参数,而ENTRYPOINT用于指定容器启动时要执行的可执行文件。可以将ENTRYPOINT看作是容器的默认入口点,而CMD则是对ENTRYPOINT指定的可执行文件的参数进行补充。

最佳实践就是:ENTRYPOINT命令用来定义主命令,CMD命令常用来给ENTRYPOINT命令提供参数。

标签: docker

本文转载自: https://blog.csdn.net/wakaka123123/article/details/141363799
版权归原作者 wakaka123123 所有, 如有侵权,请联系我们删除。

“Dockerfile中的RUN、CMD、ENTRYPOINT的区别详解”的评论:

还没有评论