多级构建期间,每个RUN命令创建的运行容器是什么?

时间:2020-08-25 07:33:59

标签: docker

我是Docker的新手,对不起,如果我的问题听起来很蠢。 以下是教科书中的dockerfile:

FROM diamol/base AS build-stage                  
RUN echo 'Building...' > /build.txt              #line 2

FROM diamol/base AS test-stage
COPY --from=build-stage /build.txt /build.txt
RUN echo 'Testing...' >> /build.txt              #line 6

FROM diamol/base
COPY --from=test-stage /build.txt /build.txt
CMD cat /build.txt

作者说:

在构建过程中,RUN指令在容器内执行命令,该命令的所有输出均保存在图像层中。

我的问题是:

Q1-由于作者提到RUN指令在构建过程中在容器内执行了一条命令,这是否意味着在第2行的第一个RUN命令中,根据{{ 1}}图片,并且此容器修改了文件的内容,然后将更改提交回diamol/base图片?在第6行中发生同样的事情,我的理解正确吗?

Q2-如果我的理解是正确的,不是我们有三个不同的diamol /基础图像—在构建阶段和测试阶段对原始的一幅和两幅进行了修改,不是很低效,因为它很小里面的文件(假设它的大小为3kb)是不同的,而图像可能高达500MB,我们有3个副本,即500MB * 3 = 1.5G?

2 个答案:

答案 0 :(得分:1)

Q1-基本图像在FROM diamol/base中保持不变,您每次都从原始图像重新启动。上一个图像由--from=build-stage使用。对于构建的每个步骤,都会创建一个图层,可以重复使用该图层以加快以后的构建速度。

Q2-图像由图层组成,这些图层在图像之间可以重复使用。可能会有一些开销,但空间不会重复。图片是不可变的,基于图片的容器包含更改。

Explanation here

Docker映像由一系列层组成。每层代表图像的Dockerfile中的一条指令。除最后一层外,每一层都是只读的。

答案 1 :(得分:1)

docker build实际上确实像一系列docker run然后执行docker commit步骤:它为每行RUN启动一个新容器,并从每个的结果。但是:

Q1。映像不一定具有名称,除非您明确告知Docker(docker tagdocker build -t),否则映像不必具有名称。如果您docker build显示的图像然后运行docker images,则应该看到diamol/base图像未修改,中间构建阶段的两个<none>图像,以及最终的图像内置。

第二季度。当您看到对图像 layer 的引用时,它仅包含前一张图像的更改。例如,build-stage映像表示为对diamol/base映像的引用(不是副本,而只是其映像ID),加上仅包含12字节/build.txt的文件系统文件。 docker history可以显示其中一些详细信息。即使基本图像很大,最终图像之间也只能共享一个副本。