docker push/pull 是原子的吗?

Is docker push/pull atomic?

问题看起来很简单。

如果在此过程中推送中断(^C?)但远程存储库已经有图像(相同name/tag),会发生什么情况? 成功上传的图层是否会覆盖现有图像,可能会损坏它? 同样,本地也可能发生同样的事情。

有没有人已经这样调查过?

不会覆盖现有图层。

这就是 docker push/pull 根据 v2 API 工作的方式:

Docker 图像由一个烧焦的清单文件和各个层组成。这些层作为 blob 存储在由它们的摘要键入的注册表中。清单文件将包含提取、安装、验证和 运行 图像所需的所有详细信息。它还包含构成图像的图层列表。

推送图像

推送镜像时,客户端会先推送图层,然后上传已签名的清单。因此,如果在上传清单之前推送中断,注册表将有一些未引用的 blob。当触发垃圾收集时,这些 blob 将被删除。

上传图层时,客户端询问注册表是否已经有该图层。如果注册表已经有层,则跳过特定层的上传。如果 registry 没有层,客户端将请求上传和 registry returns a URL 客户端可以使用它来上传层。图层可以分块上传,也可以作为整体单块上传。上传所有块后,客户端必须将层的摘要发送到注册表,注册表将验证该层的摘要,如果上传内容的摘要匹配,则 return 成功消息。 只有在验证摘要后才认为上传完成。

所有层都被推送后,客户端上传图像清单文件。注册表检查它是否具有清单中的所有层引用,如果没有,return 会出现适当的错误,例如 BLOB_UNKNOWN

正在拉取镜像

拉取镜像的方式类似,但顺序相反。 拉取镜像时,客户端会先请求镜像清单,然后下载它没有的层。仅当摘要被验证时下载才完成。