在不同主机上获得可重现的 docker 层

zel*_*gas 5 docker dockerfile

问题:我无法使用完全相同的内容重现 docker 层(在一台机器上或在从 git repo 构建某些内容的 CI 集群中)

考虑这个简单的例子

$ echo "test file" > test.txt
$ cat > Dockerfile <<EOF
FROM alpine:3.8

COPY test.txt /test.txt
EOF
Run Code Online (Sandbox Code Playgroud)

如果我在一台启用缓存的机器上构建图像,那么复制文件的最后一层将在图像之间共享

$ docker build -t test:1 .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM alpine:3.8
3.8: Pulling from library/alpine
cd784148e348: Already exists
Digest: sha256:46e71df1e5191ab8b8034c5189e325258ec44ea739bba1e5645cff83c9048ff1
Status: Downloaded newer image for alpine:3.8
 ---> 3f53bb00af94
Step 2/2 : COPY test.txt /test.txt
 ---> decab6a3fbe3
Successfully built decab6a3fbe3
Successfully tagged test:1

$ docker build -t test:2 .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM alpine:3.8
 ---> 3f53bb00af94
Step 2/2 : COPY test.txt /test.txt
 ---> Using cache
 ---> decab6a3fbe3
Successfully built decab6a3fbe3
Successfully tagged test:2
Run Code Online (Sandbox Code Playgroud)

但是在禁用缓存(或只是使用另一台机器)的情况下,我得到了不同的哈希值。

$ docker build -t test:3 --no-cache .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM alpine:3.8
 ---> 3f53bb00af94
Step 2/2 : COPY test.txt /test.txt
 ---> ced4dff22d62
Successfully built ced4dff22d62
Successfully tagged test:3
Run Code Online (Sandbox Code Playgroud)

同时history命令显示文件内容相同

$ docker history test:1
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
decab6a3fbe3        6 minutes ago       /bin/sh -c #(nop) COPY file:d9210c40895e

$ docker history test:3
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
ced4dff22d62        27 seconds ago      /bin/sh -c #(nop) COPY file:d9210c40895e
Run Code Online (Sandbox Code Playgroud)

我错过了什么还是这种行为是设计使然?

是否有任何技术可以获得可复制/可重用层,不会强迫我执行以下操作之一

  1. 跨机器共享docker缓存
  2. 在构建下一个之前做一个“上一个”图像的拉取

最终,这个问题阻止我通过不断变化的应用程序代码获得薄层,同时将我的依赖层保持在单独且不经常更改的层中。

zel*_*gas 2

经过一些额外的谷歌搜索后,我发现了一篇很棒的文章,描述了这个问题的解决方案。

从 1.13 开始,docker 有--cache-from一个选项可以用来告诉 docker 查看另一个镜像的层。重要的是 - 应该显式地拉取图像才能使其工作+您仍然需要指出要拍摄的图像。它可能是latest您拥有的任何其他“滚动”图像。

鉴于此,遗憾的是,无法在“隔离”中生成相同的层,但cache-from解决了根本问题 - 如何在 ci 构建期间最终重用某些层。