Caching 如何设置docker在每个构建步骤上使用注册表缓存

Caching 如何设置docker在每个构建步骤上使用注册表缓存,caching,docker,docker-registry,Caching,Docker,Docker Registry,我有两台带有docker的服务器和一台带有我的私有注册表的服务器 我在第一台机器上构建了Dockerfile;然后我将图像推送到注册表 是否可以使用注册表中的缓存立即在第二台计算机上构建Dockerfile?如果没有,是否有任何方法可以加快构建“几乎”相同的DockerFile,而不必编写自己的缓存 它试图设置注册表镜像,但没有帮助。对于docker>1.10,我发现了有关此问题的信息: 鉴于此Dockerfile FROM busybox RUN mkdir this-is-a-test RU

我有两台带有docker的服务器和一台带有我的私有注册表的服务器

我在第一台机器上构建了Dockerfile;然后我将图像推送到注册表

是否可以使用注册表中的缓存立即在第二台计算机上构建Dockerfile?如果没有,是否有任何方法可以加快构建“几乎”相同的DockerFile,而不必编写自己的缓存


它试图设置注册表镜像,但没有帮助。

对于docker>1.10,我发现了有关此问题的信息:

鉴于此Dockerfile

FROM busybox
RUN mkdir this-is-a-test
RUN echo "hello world"
运行
docker build-t缓存测试。

然后我们可以通过
docker history caching test

3e4a484f0e67        About an hour ago   /bin/sh -c echo "Hello world!"                  0 B                 
6258cdec0c4b        About an hour ago   /bin/sh -c mkdir this-is-a-test                 0 B                 
47bcc53f74dc        9 weeks ago         /bin/sh -c #(nop) CMD ["sh"]                    0 B                 
<missing>           9 weeks ago         /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff   1.113 MB  
这是Docker历史输出的第二层到顶层

为了使用“保存并加载”重新创建缓存,需要保存作为父对象引用的所有图像和层。在实践中,这通常意味着您需要在同一个命令中保存每个层以及“来自图像”

docker save caching test 6258cdec0c4b busybox>caching test.tar
——请注意,我们还可以为save命令指定层名而不是ID

让我们清除所有内容,然后从tar文件重新加载图像。
dockerrmi$(dockerimages-q)
。确认没有图像存在

然后运行
docker load-i缓存测试.tar
。如果您查看这些图像,您将看到busybox,然后是缓存测试。运行
docker history caching test
将显示与最初构建映像时完全相同的输出。这是因为父/子关系是通过保存和加载保留的。您甚至可以运行
docker inspect caching test | grep Parent
,查看与父层完全相同的ID

运行同一Dockerfile的重建将显示正在使用缓存

Sending build context to Docker daemon 5.391 MB
Step 1 : FROM busybox
 ---> 47bcc53f74dc
Step 2 : RUN mkdir this-is-a-test
 ---> Using cache
 ---> 6258cdec0c4b
Step 3 : RUN echo "hello world"
 ---> Using cache
 ---> 3e4a484f0e67
Successfully built 3e4a484f0e67
编辑:以下仅适用于docker 1.10之前的

在第二台机器上,您可以在构建新机器之前,从注册表上的第一个docker文件中提取图像

这样,您就可以确保第二台机器上存在每一层

docker引擎不会在每次构建一个层时查询注册表(它甚至不知道),它会太慢/太重,因此我不认为有其他方法。

注意:已关闭,因为已合并

例如,它允许在
--cache from
中指定来自先前CI构建的映像

添加了指定生成时用作缓存源的图像的功能。这些映像不需要具有本地父链,并且可以从其他注册表中提取。用户需要确保仅使用受信任的图像作为源

用法:

看,谢谢

作者:

如果有人像我一样疯狂地重复使用层,那么“窍门”就是将你正在重建的图像(并且已经拉出来了)和它在
中用作基础的图像从
传递到
--cache

示例:
Dockerfile
用于图像
自定义文件:0.1

为了在其他主机中重建而不再次执行
apt get
,您需要:

这可能看起来太明显了,但我已经为此奋斗了很长时间,直到我知道你也需要包括基本图像


对于Docker版本>=19.03,您可以使用新的BuildKit功能,以避免在构建之前必须拉取远程映像。通过设置DOCKER\u BuildKit环境变量激活BuildKit,然后使用BuildKit\u inline\u cache build参数启用内联缓存,将生成缓存与映像一起存储在注册表中,如下所示:

export DOCKER_BUILDKIT=1
docker build -t registry/imagename:tag --cache-from registry/imagename:tag --build-arg BUILDKIT_INLINE_CACHE=1 .
docker push registry/imagename:tag

感谢您提供此解决方案。

您尝试过吗@JosipIvic是的,但是构建忽略了从私有注册表中提取的层。对不起,这不是我在Docker 1.11上观察到的。拉取图像并不是拉取图像的每一层
docker history
显示除最后一层之外的所有层,并且
docker build
从头开始重建。@dynamic\u cast哇,你是对的,我不知道这个行为是什么时候出现的,但我很确定不久前我说的是对的。我会调查的。我也发现了这个帖子。我需要docker>1.9.1,这样我就不能依赖旧的行为。你能将你的答案更新为精确吗?这只在Docker 1.10之前有效?我添加了一个在另一个问题上找到的解决方法,我测试了它,它有效,即使它更麻烦谢谢你的回答。我最终在我的CI环境中完成了这项工作。除了您的答案之外:使用此命令
docker save image_NAME$(docker history-q image_NAME | tail-n+2 | grep-v\| tr'\n'')>TAR\u FILE_NAME.TAR
,还可以保存图像的所有可用层。总而言之,尽管我必须存储非常大的工件(所有层都必须保存,并且这种方法不允许像注册表那样重用推送层),但这种变通方法仍然有效。我希望将来Docker会解决这个问题。正式包含在v1.13版本中,@luka5z谢谢。我在docker compose中登陆时也根据任何想法编辑了答案?@Kilian不,我没有。当我输入
docker--version
时,我得到17,但当我输入
docker compose--version
时,我得到1.14。你能澄清一下吗,
docker pull myimage:v1.0
docker build --cache-from myimage:v1.0 -t myimage:v1.1 .
FROM base_image:2.2.1
RUN apt-get update && apt-get install gource
COPY myscript.sh /myscript.sh
docker pull custom-gource:0.1
docker build --cache-from=base_image:2.2.1,custom-gource:0.1 . -t custom-gource:0.2
export DOCKER_BUILDKIT=1
docker build -t registry/imagename:tag --cache-from registry/imagename:tag --build-arg BUILDKIT_INLINE_CACHE=1 .
docker push registry/imagename:tag