了解 docker 层和未来的变化

Understanding docker layers and future changes

So,

Each Docker image references a list of read-only layers that represent filesystem differences. Layers are stacked on top of each other to form a base for a container’s root filesystem.

并且,

Because each container has its own thin writable container layer, and all changes are stored in this container layer, this means that multiple containers can share access to the same underlying image and yet have their own data state.

also

Layers of a Docker image are essentially just files generated from running some command. You can view the contents of each layer on the Docker host at /var/lib/docker/aufs/diff.

现在,问题,

总的来说,每个图像都包含其 parent 图像,可以是嵌入字节,也可以是对本地缓存中图像的 "hard" 引用(如果它已经存在)。

"parent" 我的意思是 Docker 文件中的 FROM: someimage 指令。

我也写了 "hard" 因为参考实际上是 parent 图像的 sha246 摘要。如果 parent 的任何一位发生变化,摘要就会不同。

这里主要有三种情况:

  1. 您从清除缓存开始(docker image ls -a 什么也没显示)。如果您 docker pull ... 来自 public 注册表的一些图像,它将嵌入 parent。 docker ps -a 应该只显示一张图片。

  2. 如果您的缓存中已经有 parent 图像,docker pull ... 将不会再次下载 parent。在这种情况下,拉取的图像会引用缓存中的 parent。

  3. 如果您从清除缓存在本地构建,docker 将下载 parent 图像并生成一个 child 图像并引用 [=81] =].

最后还是一样的结果。如果您用更新版本替换 parent 图像,摘要将不一样。

Docker 不允许您删除其他图片引用的图片。当您将图像推送到注册表时,parent 会被嵌入(我在这里忽略了注册表端的缓存行为)。我认为您也可以使用 docker exportdocker import 嵌入 parent,但我还没有尝试过。例如,docker export B,然后从 docker 缓存中删除 A 和 B,然后 docker import B 应该只显示一张图像。

您可以使用

获得实际的 parent 关系
docker image inspect <image-id> | grep -E "Id|Parent"

将其与

合并
docker image ls -a --digests

检查关系。

更多信息。

构建映像时,会发生以下步骤:

  1. 构建上下文通过 docker 守护程序发送到主机。这基本上是您的 Docker 文件所在目录中的所有文件。这就是为什么使用 .dockerignore 只发送在您的 Docker 中复制的文件很重要文件。
  2. docker 守护程序使用 Docker 文件中的 FROM 指令创建一个临时容器。这是导入的图像,包括它自己的导入图像。然后 Dockefile 中的每条指令都在该容器内执行。当在临时容器中进行持久更改(如 COPY'ing)时,它会保存其状态。这有效地为最终图像添加了一层。
  3. DOCKERFILE 指令执行完毕后,临时容器将被销毁。您剩下的是最终图像。

您可以使用以下命令查看图像中的所有图层 docker history <image-id>

请注意,这提供了一种调试 Docker 文件的简便方法。您应该在 Docker 文件中看到与持久指令对应的层的 ID。您可以使用 docker run --rm -it <id next to layer> sh 从任何层创建一个新容器并手动执行后面的 Docker 文件指令。