Docker中心图像缓存似乎不起作用

时间:2016-01-19 21:15:02

标签: docker docker-registry dockerhub

我们在circleci上有一个持续的集成管道,它执行以下操作:

  1. 从缓存目录加载repo / image:mytag1,以便能够使用缓存层
  2. 构建新版本:docker build -t repoimage:mytag2
  3. 使用docker save
  4. 将新版本保存到缓存目录
  5. 运行测试
  6. 推送到docker hub:docker push repo / image:mytag2
  7. 问题在于步骤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
    

    那为什么每次都要重新推动所有图像呢?

2 个答案:

答案 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的独立主机上运行dockerdocker-compose .1,但这不应该有任何区别。

注册表版本可能也存在差异,我感觉(但我不是100%肯定)DockerHub上的一些旧版本仍然在注册表v1上运行,较新的版本始终在{{1}上运行 - 所以你可以尝试创建一个新的仓库,看看问题是否仍然存在。

请注意,上述标签的行为仅在推送相同的图像名称时适用,如果您使用其他名称推送相同的图像图层,则始终需要推送所有图层,尽管所有图层都应该已经存在于注册表中,因此我猜v2repo/image:mytag1实际上转到repoimage:mytag2,丢失的斜杠只是一个错字。

另一个原因可能是您的图像是在Circle CI上的不同主机上构建的,但是您还应该获得不同的图层ID,所以我认为这不太可能。

我建议手动构建图像并尝试重现该问题,或者就此问题与Circle CI联系。