DockerfileRUN、CMD、ENTRYPOINT区别
- RUN 在新图层中执行命令并创建新图像。例如,它通常用于安装软件包。
- CMD 设置默认命令和/或参数,当docker容器运行时,可以从命令行覆盖这些命令和/或参数。
- ENTRYPOINT 配置将作为可执行文件运行的容器。
Docker图像和图层
当Docker运行一个容器时,它会在其中运行一个镜像。此镜像通常通过执行Docker指令构建,该指令在现有镜像或OS分布之上添加层。OS分布是初始图像,每个添加的层都会创建一个新镜像。
Shell和Exec形式
所有三个指令(RUN,CMD和ENTRYPOINT)都可以用shell形式或exec形式指定。让我们首先熟悉这些形式,因为形式通常比指令本身更容易引起混淆。
shell形式
<instruction> <command>复制代码
Examples:
RUN apt-get install python3CMD echo"Hello world"
ENTRYPOINT echo"Hello world"
复制代码
当以shell形式执行指令时,它会调用/bin/sh -c 并进行正常的shell处理。例如,Dockerfile中的以下代码段
ENV name John DowENTRYPOINT echo"Hello, $name"
复制代码
当容器运行docker run -it 时将输出
Hello, John Dow复制代码
注意:变量名称将替换为其值。
Exec形式
这是CMD和ENTRYPOINT指令的首选形式。
<instruction> ["executable", "param1", "param2", ...]复制代码
Examples:
RUN ["apt-get", "install", "python3"]CMD ["/bin/echo", "Hello world"]
ENTRYPOINT ["/bin/echo", "Hello world"]
复制代码
当以exec形式执行指令时,它直接调用可执行文件,并且不会发生shell处理。例如,Dockerfile中的以下代码段
ENV name John DowENTRYPOINT ["/bin/echo", "Hello, $name"]
复制代码
当容器运行docker run -it 时将输出
Hello, $name复制代码
注意:变量名称未替换。
怎么运行bash?
如果你需要运行bash(或任何其他解释器如sh),使用exec形式与/bin/bash作为可执行文件。在这种情况下,将进行正常的shell处理。例如,Dockerfile中的以下代码段
ENV name John DowENTRYPOINT ["/bin/bash", "-c", "echo Hello, $name"]
复制代码
当容器运行docker run -it 时将输出
Hello, John Dow复制代码
RUN
RUN指令允许您安装应用程序和程序包。它在当前镜像之上执行任何命令,并通过提交结果来创建新层。通常,您会在Dockerfile中找到多个RUN指令。
RUN有两种形式
- RUN (shell 形式)
- RUN ["executable", "param1", "param2"] (exec 形式)
RUN指令的一个很好的例子是安装多个版本控制系统包:
RUN apt-get update && apt-get install -y bzr
cvs
git
mercurial
subversion
复制代码
注意:apt-get update和apt-get install在单个RUN指令中执行。这样做是为了确保安装最新的软件包。如果apt-get install位于分开的RUN指令中,那么它将重用apt-get update添加的层,这可能是很久以前创建的。建议多个指令用&&隔开在一个run中执行。
CMD
CMD指令允许您设置默认命令,该命令仅在您运行容器不指定命令时候运行。如果Docker容器使用命令运行,则将忽略默认命令。如果Dockerfile具有多个CMD指令,则忽略除最后一个CMD指令之外的所有指令。
CMD有三种形式:
- CMD ["executable","param1","param2"] (exec 形式, 推荐)
- CMD ["param1","param2"] (以exec形式为ENTRYPOINT设置其他默认参数)
- CMD command param1 param2 (shell 形式)
第一和第三种形式在Shell和Exec部分进行了解释。第二种exec形式和ENTRYPOINT指令一起使用。如果容器在没有命令行参数的情况下运行,它将设置将在ENTRYPOINT参数之后添加的默认参数。参见ENTRYPOINT。
我们来看看CMD指令是如何工作的。Dockerfile中的以下片段
CMD echo"Hello world"复制代码
当容器运行docker run -it 时将输出
Hello world复制代码
但是当容器使用命令运行时,例如, docker run -it /bin/bash,忽略CMD并改为运行bash指令:
root@7de4bed89922:/#复制代码
ENTRYPOINT
ENTRYPOINT指令允许您配置将作为可执行文件运行的容器。它看起来类似于CMD,因为它还允许您使用参数指定命令。区别在于当Docker容器使用命令行参数运行时,ENTRYPOINT命令不会忽略参数。(有一种方法可以忽略ENTTRYPOINT,但你不太可能这样做。)
ENTRYPOINT 有两种形式:
- ENTRYPOINT ["executable", "param1", "param2"] (exec 形式,推荐)
- ENTRYPOINT command param1 param2 (shell 形式)
选择ENTRYPOINT形式时要非常小心,因为不同形式执行结果会有很大差异。
Exec 形式
ENTRYPOINT的Exec形式允许您设置命令和参数,然后使用任一形式的CMD来设置更可能更改的其他参数。使用ENTRYPOINT参数,而可以通过Docker容器运行时提供的命令行参数覆盖CMD。例如,Dockerfile中的以下代码段
ENTRYPOINT ["/bin/echo", "Hello"]CMD ["world"]
复制代码
当容器运行docker run -it 时将输出
Hello world复制代码
但是当容器运行docker run -it John时,将输出
Hello John复制代码
Shell 形式
Shell形式的ENTRYPOINT忽略任何CMD或docker运行命令行参数。
使用RUN指令通过在初始镜像上添加层来构建镜像。
在构建可执行的Docker镜像时,首选ENTRYPOINT的CMD形式。另外如果需要提供额外的默认参数,可以在docker容器运行时从命令行覆盖,请使用CMD。
如果需要提供默认命令和/或在docker容器运行时可以从命令行覆盖的参数,请选择CMD。
以上是 DockerfileRUN、CMD、ENTRYPOINT区别 的全部内容, 来源链接: utcz.com/z/514990.html