Docker 壁球和层:哪些层被合并,哪些仍然共享

Eug*_*yer 4 docker

提示:我知道这个问题,但它并没有完全/完全回答我的问题,或者或多或少没有针对它(但你可以从中得出一些 - 我会说应该有一个是/否的问题 - 在这里它是 )。

案件:

  • 假设我有 3 个图像,一个称为 BASE,一个 CHILDa 和 CHILDb,两个孩子都有FROM BASE
  • 假设 BASE 的大小为 1GB 并假设我们不知道或对它是否被压扁特别感兴趣,因为这无关紧要(恕我直言)
  • CHILDa 和 CHILDb 都添加了 10 层,每个层的大小为 500MB
  • 假设我们docker build --squash CHILDa在创建 CHILDa 和 CHILDb 时使用

题:

从注册表中提取 CHILDa 和 CHILDb 时,我知道将首先提取 BASE 层。现在,我的问题是,驱动器上图像的确切大小是多少:

a) 1GB(base) + 500MB(CHILDa) + 500MB(childB)=2GB
b) (1GB + 500MB) + (1GB + 500MB)=3GB

那么 BASE 的层是在非--sqaush情况下共享的(这将是a))还是它们不共享,b)然后

我知道,当 CHILDa 被构建和压扁时,BASE 中的层不应该被压扁,只有在 CHILDa 中创建的层被压扁为一层,所以历史应该是这样的

  • 基础层1
  • 基础层2
  • 基础层3
  • ...
  • CHILDa LAYER1(压扁)

这意味着,所有的 BASE 层都应该在传输时与 CHILDb 共享,并且在同时拉取 CHILDa 和 CHILDb 时在磁盘空间方面也共享。这将意味着a)将是答案。

我问这个问题是为了有一个明确的答案,而不是根据文档寻找建议或暗示。甚至可能支持进行测试?文档和技术实现不匹配已经不是第一次了(在 docker 中)

BMi*_*tch 5

答案是 A。您可以通过检查结果图像轻松了解 Docker 正在做什么:

首先构建两个镜像:

$ docker build -t jenkins-blueocean:full .
$ docker build -t jenkins-blueocean:squash --squash .
Run Code Online (Sandbox Code Playgroud)

比较用于图像的总磁盘空间(计算基本图像,在本例中为 jenkins/jenkins):

$ docker image ls jenkins/jenkins:2.77         
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jenkins/jenkins     2.77                1a057287c665        6 weeks ago         814MB
$ docker image ls jenkins-blueocean:full
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jenkins-blueocean   full                773f9e1cbd94        3 minutes ago       1.29GB
$ docker image ls jenkins-blueocean:squash
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jenkins-blueocean   squash              9a8816dcc900        2 minutes ago       1.28GB
Run Code Online (Sandbox Code Playgroud)

此磁盘空间是累积的,并且会将不同图像中使用的层数加倍。所以我们需要看看实际的层。使用以下命令比较三个图像(基本、完整和压缩)的层docker inspect

$ docker inspect -f '{{json .RootFS.Layers}}' jenkins/jenkins:2.77 | jq .
[
  "sha256:45f0f161f0749d09482ed1507925151b22b1f8c0c85970fe0857d61e530264b4",
  "sha256:560ec518567f4117ed651db78b9c46eee39e00f38a87d6200ad7c87b79432064",
  "sha256:deccd4ec00609f5f711578af469ce4ff43a5c73efc52517fc8ca362ebd36860c",
  "sha256:23543e96fe44ca57a96d8552a6d9d218f7aa93b928a1ec8bafcaa9df3cc5723b",
  "sha256:3de9ccb39b3bcf90c9215a49a84b340fedad87840d0580ffe0f0e0e8a1cb1f53",
  "sha256:559298d0ee994bb9f12a77b1acc6fdfb6c7120cbcadfd640f7a9d171729b2cb1",
  "sha256:4dc9d0cb0b3ca0f565aa29c7762f7322ece1e1fb51711feac3a52f3c20a28d2f",
  "sha256:93d818bcd1d5eb6c689e6964e89feb8a8a3a394a998552c540b7db74986266c7",
  "sha256:ac3d4345fe0474e18265fbb999fe6ab1c077fbb59876317406c7974c75c7ab5d",
  "sha256:83a60a36cc44ca6fdab64823e805a853106be334239eb9d43cc1b220bb6ad238",
  "sha256:7c78d70f156aaaee25540c9100ca28b68b554a966d448079896c413ae71a0e5d",
  "sha256:cfd8defeb8a79686260691ce89a36772b21af0f736628492c835bb8a5740b817",
  "sha256:fc4dc905efd22f932b74f95b53904736bebf52c2033e9853c54efb0b3f01560f",
  "sha256:456fa2e1bb798ba4ccc5d433013973772b673dfff1f1386f18ceffe7d18132da",
  "sha256:2446924bd5315bf6c46e8a5db2b61247da4ded48f4de148c15f8f5a2f9b1e91a",
  "sha256:5a4416e8de72a14e97b53484e6016cc8a5b79398a25eb3b80fa099740b9f32e3",
  "sha256:20901b1036e739e01c99d83e461059b3974003835a31e473f348fd70ece6c4e3",
  "sha256:6d9d9244ead270d545d5de253a6ebb95398a7c63b10977c5cf7345b1cbf7d201",
  "sha256:056fab22f880b32a4bbe4725b5b227891290097fd3791af452e52eb98b02cfb4",
  "sha256:18a8691ee145f81f617bf788f39617f46d84b9924911317e6226139074b1f3e1"
]
Run Code Online (Sandbox Code Playgroud)

这个基本图像上升到第 18a8691 层...与完整的比较:

$ docker inspect -f '{{json .RootFS.Layers}}' jenkins-blueocean:full | jq .
[
  "sha256:45f0f161f0749d09482ed1507925151b22b1f8c0c85970fe0857d61e530264b4",
  "sha256:560ec518567f4117ed651db78b9c46eee39e00f38a87d6200ad7c87b79432064",
  "sha256:deccd4ec00609f5f711578af469ce4ff43a5c73efc52517fc8ca362ebd36860c",
  "sha256:23543e96fe44ca57a96d8552a6d9d218f7aa93b928a1ec8bafcaa9df3cc5723b",
  "sha256:3de9ccb39b3bcf90c9215a49a84b340fedad87840d0580ffe0f0e0e8a1cb1f53",
  "sha256:559298d0ee994bb9f12a77b1acc6fdfb6c7120cbcadfd640f7a9d171729b2cb1",
  "sha256:4dc9d0cb0b3ca0f565aa29c7762f7322ece1e1fb51711feac3a52f3c20a28d2f",
  "sha256:93d818bcd1d5eb6c689e6964e89feb8a8a3a394a998552c540b7db74986266c7",
  "sha256:ac3d4345fe0474e18265fbb999fe6ab1c077fbb59876317406c7974c75c7ab5d",
  "sha256:83a60a36cc44ca6fdab64823e805a853106be334239eb9d43cc1b220bb6ad238",
  "sha256:7c78d70f156aaaee25540c9100ca28b68b554a966d448079896c413ae71a0e5d",
  "sha256:cfd8defeb8a79686260691ce89a36772b21af0f736628492c835bb8a5740b817",
  "sha256:fc4dc905efd22f932b74f95b53904736bebf52c2033e9853c54efb0b3f01560f",
  "sha256:456fa2e1bb798ba4ccc5d433013973772b673dfff1f1386f18ceffe7d18132da",
  "sha256:2446924bd5315bf6c46e8a5db2b61247da4ded48f4de148c15f8f5a2f9b1e91a",
  "sha256:5a4416e8de72a14e97b53484e6016cc8a5b79398a25eb3b80fa099740b9f32e3",
  "sha256:20901b1036e739e01c99d83e461059b3974003835a31e473f348fd70ece6c4e3",
  "sha256:6d9d9244ead270d545d5de253a6ebb95398a7c63b10977c5cf7345b1cbf7d201",
  "sha256:056fab22f880b32a4bbe4725b5b227891290097fd3791af452e52eb98b02cfb4",
  "sha256:18a8691ee145f81f617bf788f39617f46d84b9924911317e6226139074b1f3e1",
  "sha256:679b85b8d42598a7ecb5988e408da49cbb3f86402fd2e5694104839ff17a7015",
  "sha256:5fa620489d92edd3e7922d9335d803ea83c148793044e0da99144152f7988437",
  "sha256:17d03c6eda4a4d989f6751bb53d7bf356309938a1076af75bdf440195471fa2b",
  "sha256:7a78b2c7c995ddab1ba675aba1c2bc54cc289ba148fd39b600f592060d98c459",
  "sha256:f56b6c3fd8713236d077a95568a58445e6d6423113c0b68c6f10bef39bd6b6ff"
]
Run Code Online (Sandbox Code Playgroud)

完整图像为图像添加了 5 层。查看被压扁的:

$ docker inspect -f '{{json .RootFS.Layers}}' jenkins-blueocean:squash | jq .
[
  "sha256:45f0f161f0749d09482ed1507925151b22b1f8c0c85970fe0857d61e530264b4",
  "sha256:560ec518567f4117ed651db78b9c46eee39e00f38a87d6200ad7c87b79432064",
  "sha256:deccd4ec00609f5f711578af469ce4ff43a5c73efc52517fc8ca362ebd36860c",
  "sha256:23543e96fe44ca57a96d8552a6d9d218f7aa93b928a1ec8bafcaa9df3cc5723b",
  "sha256:3de9ccb39b3bcf90c9215a49a84b340fedad87840d0580ffe0f0e0e8a1cb1f53",
  "sha256:559298d0ee994bb9f12a77b1acc6fdfb6c7120cbcadfd640f7a9d171729b2cb1",
  "sha256:4dc9d0cb0b3ca0f565aa29c7762f7322ece1e1fb51711feac3a52f3c20a28d2f",
  "sha256:93d818bcd1d5eb6c689e6964e89feb8a8a3a394a998552c540b7db74986266c7",
  "sha256:ac3d4345fe0474e18265fbb999fe6ab1c077fbb59876317406c7974c75c7ab5d",
  "sha256:83a60a36cc44ca6fdab64823e805a853106be334239eb9d43cc1b220bb6ad238",
  "sha256:7c78d70f156aaaee25540c9100ca28b68b554a966d448079896c413ae71a0e5d",
  "sha256:cfd8defeb8a79686260691ce89a36772b21af0f736628492c835bb8a5740b817",
  "sha256:fc4dc905efd22f932b74f95b53904736bebf52c2033e9853c54efb0b3f01560f",
  "sha256:456fa2e1bb798ba4ccc5d433013973772b673dfff1f1386f18ceffe7d18132da",
  "sha256:2446924bd5315bf6c46e8a5db2b61247da4ded48f4de148c15f8f5a2f9b1e91a",
  "sha256:5a4416e8de72a14e97b53484e6016cc8a5b79398a25eb3b80fa099740b9f32e3",
  "sha256:20901b1036e739e01c99d83e461059b3974003835a31e473f348fd70ece6c4e3",
  "sha256:6d9d9244ead270d545d5de253a6ebb95398a7c63b10977c5cf7345b1cbf7d201",
  "sha256:056fab22f880b32a4bbe4725b5b227891290097fd3791af452e52eb98b02cfb4",
  "sha256:18a8691ee145f81f617bf788f39617f46d84b9924911317e6226139074b1f3e1",
  "sha256:e05668bb7cbab8f964ea3512a9ce41568330218e0e383693ad9edfd1befce9aa"
]
Run Code Online (Sandbox Code Playgroud)

它只添加了一个新层。基本图像本身没有被压缩。

在磁盘上,每一层仅存储一次,因此您只需计算一次基本映像的磁盘使用量。

请注意,我不建议在大多数情况下压缩图像。它打破了图像内部早期图层的图像图层缓存的价值。相反,我建议组织 Dockerfile 以最大化层缓存的价值,如果有一些系统开销,则使用多阶段构建将层降低到单个副本。

  • 顺便提一下,在我几乎所有的测试中,即使在顶部有大约 80 层的图像上,挤压的影响也很小,即使图像大小被认为相当大(1.5GB)。我认为这仍然归结为使用最佳实践在您做了一些事情之后立即清理您的操作,这是保持图像较小的唯一方法。像 `apt-get update && install && rm /var/lib/apt && autoremove` 都在一行中,包括安装 build-essentials 并删除它们或更好 - 创建一个构建器镜像来构建工件并安装在镜像上 (2认同)