我是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?
答案 0 :(得分:1)
Q1-基本图像在FROM diamol/base
中保持不变,您每次都从原始图像重新启动。上一个图像由--from=build-stage
使用。对于构建的每个步骤,都会创建一个图层,可以重复使用该图层以加快以后的构建速度。
Q2-图像由图层组成,这些图层在图像之间可以重复使用。可能会有一些开销,但空间不会重复。图片是不可变的,基于图片的容器包含更改。
Docker映像由一系列层组成。每层代表图像的Dockerfile中的一条指令。除最后一层外,每一层都是只读的。
答案 1 :(得分:1)
docker build
实际上确实像一系列docker run
然后执行docker commit
步骤:它为每行RUN
启动一个新容器,并从每个的结果。但是:
Q1。映像不一定具有名称,除非您明确告知Docker(docker tag
,docker build -t
),否则映像不必具有名称。如果您docker build
显示的图像然后运行docker images
,则应该看到diamol/base
图像未修改,中间构建阶段的两个<none>
图像,以及最终的图像内置。
第二季度。当您看到对图像 layer 的引用时,它仅包含前一张图像的更改。例如,build-stage
映像表示为对diamol/base
映像的引用(不是副本,而只是其映像ID),加上仅包含12字节/build.txt
的文件系统文件。 docker history
可以显示其中一些详细信息。即使基本图像很大,最终图像之间也只能共享一个副本。