So,
每个Docker映像均引用代表文件系统差异的只读层的列表。各个层堆叠在一起,形成容器根文件系统的基础。
和
因为每个容器都有其自己的可写薄容器层,并且所有更改都存储在该容器层中,所以这意味着多个容器可以共享访问到相同的基础映像 >却拥有自己的数据状态。
和also,
Docker镜像的层实际上只是通过运行某些命令而生成的文件。您可以在
/var/lib/docker/aufs/diff
上查看Docker主机上每一层的内容。
现在,问题
A < B < C < D
等A
,则只要Docker映像B, C, D
不会在未触及更改的情况下也能看到更改建立他们?例如,添加从未有过的/etc/apt/sources.list.d/somethingnew
。A < X < Y < Z
,那么以上更改也将反映在X, Y, Z
中,对吗? A
的更改是对同一文件进行的,而在构建B, C, D
时将进行更改,那么会发生什么呢?例如,让我们简单起见,docker映像B, C, D
每个仅在其层中添加pkgB,pkgC和pkgD。如果在A
构建完成后向B, C, D
添加pkgA,会发生什么情况? -我猜应该有一个单一版本的真理,因为对于单个系统,其中包含什么软件包,那么这种情况会是什么? A
中的软件包怎么办?这样应该可以吧?其余Docker映像也会看到更改吗? 答案 0 :(得分:1)
总体而言,每个图像都包含其父图像,可以是嵌入式字节,也可以是对本地缓存中图像的“硬”引用(如果已有的话)。
“父母”是指Dockerfile中的FROM: someimage
指令。
我还写了“ hard”,因为该引用实际上是父图像的sha246摘要。如果父级的任何一位更改,则摘要将有所不同。
这里有三种主要情况:
您首先要使用明确的缓存(docker image ls -a
什么也不显示)。如果您docker pull ...
来自公共注册表的某些图像,则其父图像将被嵌入。 docker ps -a
应该只显示一张图像。
但是,如果缓存中已经有父映像,则docker pull ...
将不会再次下载父映像。在这种情况下,提取的图像会在缓存中引用父对象。
如果您从明确的缓存中进行本地构建,则docker将下载父映像并生成一个引用父映像的子映像。
最后仍然是相同的结果。如果将父映像替换为较新的版本,则摘要将不同。
如果另一个映像引用了Docker,Docker将不允许您删除它。当您将映像推送到注册表时,父级已嵌入(我在此处跳过了注册表端的缓存行为)。我认为您也可以使用docker export
和docker import
来嵌入父对象,但我还没有尝试过。例如,docker export B
,然后从docker缓存中删除A和B,而docker import B
应该只显示一个图像。
您可以使用来获得实际的父母关系
docker image inspect <image-id> | grep -E "Id|Parent"
与
组合docker image ls -a --digests
检查关系。
更多信息。
构建映像时,将发生以下步骤:
.dockerignore
仅发送Dockerfile中COPY的文件很重要的原因。您可以使用来查看图像中的所有图层
docker history <image-id>
请注意,这提供了调试Dockerfile的便捷方法。您应该在Dockerfile中看到对应于持久性指令的层的ID。您可以使用docker run --rm -it <id next to layer> sh
从任何层创建一个新容器,并手动执行随后的Dockerfile指令。