我们在circleci上有一个持续的集成管道,它执行以下操作:
问题在于步骤5.每次推送步骤需要5分钟。如果我理解正确的话,docker hub就是为了缓存图层,所以如果它们没有更新,我们就不必重新推送像基本图像和依赖项这样的东西。
我连续两次运行构建,我看到正在推送的层的哈希中有很多交叉。然而,与“图像已存在”相比,我看到“图像已成功推送”。
Here's构建1的docker push的输出,以及here's build 2
如果您对这两个文件进行区分,您会发现每个版本中只有2个图层不同:
< ca44fed88be6: Buffering to Disk
< ca44fed88be6: Image successfully pushed
< 5dbd19bfac8a: Buffering to Disk
< 5dbd19bfac8a: Image successfully pushed
---
> 9136b10cfb72: Buffering to Disk
> 9136b10cfb72: Image successfully pushed
> 0388311b6857: Buffering to Disk
> 0388311b6857: Image successfully pushed
那为什么每次都要重新推动所有图像呢?
答案 0 :(得分:1)
使用不同的标签会创建一个不同的图像,当按下该图像时,不能依赖缓存。
例如两个命令:
$ docker commit -m "thing" -a "me" db65bf421f96 me/thing:v1
$ docker commit -m "thing" -a "me" db65bf421f96 me/thing:v2
尽管它们是从相同的图像(db65bf421f96)创建的,但却完全不受影响。推送时,dockerhub必须将它们视为完全独立的图像,如下所示:
$ docker images
REPOSITORY TAG IMAGE ID
me/thing v2 f14aa8ac6bae
me/thing v1 c7d72ccc1d71
图像ID是唯一的,因此即使图像标记不同,图像也是唯一的。
你可以说“docker应该认为它们有点相同”,因此将它们视为可缓存。但它(尚未)。
在您的示例中,我唯一感到惊讶的是您根本没有任何重复的图像ID。
“构建自己的图像”中的权威性(如果解释性较差)documentation can be found at docker。
答案 1 :(得分:0)
该过程应如您所述。事实上,我们正在以这种方式构建所有图像而没有任何问题。通常,最顶层只有一些更改,只有那些被推送到注册表 - 否则图像层的整个概念将是无用的。
有关示例,请参阅here。只有两个最顶层已经更改,被推送到:latest
而对于:4.0.2
,根本没有推动。我们使用git标签标记图像,对于某些项目,我们甚至使用git describe
标记图像 - 以获取回滚功能,以防万一。
您也可以从GitHub获取项目源代码以进行试用。
有关设置的一些注意事项:我们使用自定义的GitLab CI,其自定义runner在具有Docker 1.9的独立主机上运行docker
和docker-compose
.1,但这不应该有任何区别。
注册表版本可能也存在差异,我感觉(但我不是100%肯定)DockerHub上的一些旧版本仍然在注册表v1
上运行,较新的版本始终在{{1}上运行 - 所以你可以尝试创建一个新的仓库,看看问题是否仍然存在。
请注意,上述标签的行为仅在推送相同的图像名称时适用,如果您使用其他名称推送相同的图像图层,则始终需要推送所有图层,尽管所有图层都应该已经存在于注册表中,因此我猜v2
和repo/image:mytag1
实际上转到repoimage:mytag2
,丢失的斜杠只是一个错字。
另一个原因可能是您的图像是在Circle CI上的不同主机上构建的,但是您还应该获得不同的图层ID,所以我认为这不太可能。
我建议手动构建图像并尝试重现该问题,或者就此问题与Circle CI联系。