HTTP API第2版

预计阅读时间:126分钟

Docker注册表HTTP API V2

介绍

所述多克尔注册表HTTP API是为了方便向搬运工发动机图像的分配的协议。它与Docker注册表实例交互,该服务用于管理有关Docker映像的信息并启用其分发。该规范涵盖了该API版本2(称为Docker Registry HTTP API V2)的操作

尽管可以使用V1注册表协议,但该体系结构存在一些问题,导致出现了此新版本。该规范的主要驱动因素是对Docker映像格式的一组更改,在 docker / docker#8093中进行了介绍。新的,自包含的图像清单简化了图像定义并提高了安全性。该规范将基于这项工作,利用清单格式的新属性来提高性能,减少带宽使用并降低后端损坏的可能性。

有关导致此规范的相关详细信息和历史记录,请参见以下问题:

范围

本规范涵盖Docker注册表和Docker核心之间交互的URL布局和协议。这将影响Docker核心注册表API和docker-registry的重写。Docker注册表实现可以实现其他API端点,但本规范未涵盖它们。

这包括以下功能:

  • 面向命名空间的URI布局
  • 用于V2映像清单格式的PUSH / PULL注册表服务器
  • 可恢复层PUSH支持
  • V2客户端库实施

尽管身份验证和授权支持会影响此规范,但协议的详细信息将留待将来的规范使用。存在相关的标头定义和错误代码,以指示客户端可能遇到的情况。

未来

在削减此规范的过程中已经讨论了某些功能。以下是不完整的列表:

  • 不可变的图像参考
  • 多种架构支持
  • 从v2兼容性表示形式迁移

这些代表的功能可能超出了本规范的范围,又超出了其他规范的范围,或者已推迟到以后的版本中。

用例

在大多数情况下,以前的注册表API的用例适用于新版本。下文介绍了不同的用例。

图片验证码

泊坞窗引擎实例想运行带有标签“ latest”的名为“ library / ubuntu”的经过验证的映像。引擎联系注册表,请求清单“ library / ubuntu:latest”。不受信任的注册表将返回清单。在继续下载各个层之前,引擎会验证清单的签名,以确保内容是从受信任的源产生的,并且没有发生篡改。下载每一层后,引擎将验证该层的摘要,以确保内容与清单指定的内容匹配。

连续推送

X公司的构建服务器在完成图像层传输之前会失去与docker注册表的连接。连接恢复后,构建服务器将尝试重新上传映像。注册表通知生成服务器已经部分尝试了上载。生成服务器通过仅发送剩余数据来完成映像文件来进行响应。

恢复拉力

X公司的连通性问题更多,但这一次是在其部署数据中心中。下载图像时,连接会在完成之前中断。客户端保留部分数据,并使用http Range请求来避免下载重复的数据。

层上传重复数据删除

公司Y的构建系统从构建过程A和B创建了两个相同的docker层。构建过程A在B之前完成了该层的上载。当过程B尝试上载该层时,注册表表明它不是必需的,因为该层是已知的。

如果进程A和B同时上载相同的层,则这两个操作将继续进行,并且第一个完成的操作将存储在注册表中(注意:我们可以使用某种锁定机制来进行修改,以防止出现堆砌的情况)。

变化

V2规范已被编写为可作为活动文档使用,仅指定确定的内容,未指定的内容将公开或保留将来的更改。仅应在API中进行无冲突的添加,并且接受的更改应避免阻止将来发生更改。

对规范进行更改时,应更新本节,以指示有何不同。(可选)我们可以开始标记规范的各个部分,以与此处列举的版本相对应。

每组更改都被赋予一个字母,该字母与应用于基准规范的一组修改相对应。这些仅供参考,除标识一组修改之外,不应在规范之外使用。

  • 记录TOOMANYREQUESTS错误代码。
ķ
  • 在清单端点中记录使用Accept和Content-Type标头。
Ĵ
  • 增加了跨存储库挂载Blob的功能。
一世
  • 阐明了对清单HEAD请求的预期行为响应。
H
  • 所有提到的tarsum都被删除了。
G
  • 使用未指定的参数澄清分页行为。
F
  • 为图层和清单指定删除API。
Ë
  • 添加了对列出注册表内容的支持。
  • 向标签API添加了分页功能。
  • 添加了支持分页的通用方法。
d
  • 允许存储库名称组件为一个字符。
  • 阐明了允许使用单个组件名称。
C
  • 添加了涵盖摘要格式的部分。
  • 添加了更多说明,即清单不能通过标签删除。
b
  • 新增了将流上传上传到PATCH blob上传的功能。
  • 更新的PUT Blob上传不再占用最终块,现在需要完整数据或不需要数据。
  • 从PUT Blob上传中删除了“ 416无法满足要求的范围”响应状态。
一种
  • 增加了对清单端点中不可变清单引用的支持。
  • 不建议使用标记删除清单。
  • 为适当的实体指定了“ Docker-Content-Digest”头。
  • 为不支持的操作添加了错误代码。

概述

本节介绍客户端流和API端点的详细信息。新API的URI布局通过利用名称空间来支持丰富的身份验证和授权模型。所有端点都将以API版本和存储库名称为前缀:

/v2/<name>/

例如,将与library/ubuntu 存储库一起使用的API端点,URI前缀为:

/v2/library/ubuntu/

该方案使用URI前缀和http方法提供了对各种操作和方法的丰富访问控制,并且可以通过多种方式进行控制。

通常,存储库名称始终是两个路径组成部分,其中每个路径组成部分均少于30个字符。V2注册表API不会强制执行此操作。存储库名称的规则如下:

  1. 存储库名称分为路径组件。存储库名称的组成部分必须至少包含一个小写字母数字字符,并可以用句点,短划线或下划线分隔。更严格地说,它必须匹配正则表达式[a-z0-9]+(?:[._-][a-z0-9]+)*
  2. 如果存储库名称包含两个或多个路径组成部分,则必须用正斜杠(“ /”)分隔。
  3. 存储库名称的总长度(包括斜杠)必须少于256个字符。

这些名称要求适用于注册表API,并且应接受其他Docker生态系统组件支持的功能的超集。

在适当的情况下,所有端点都应支持积极的http缓存,压缩和范围标头。新的API尝试在可能的情况下利用HTTP语义,但可能会违反标准以实现目标功能。

有关各个端点的详细信息,请参阅“详细信息” 部分。

失误

在json响应正文中,可操作的失败条件在其相关部分中详细介绍,作为4xx响应的一部分报告。一个或多个错误将以以下格式返回:

{
    "errors:" [{
            "code": <error identifier>,
            "message": <message describing condition>,
            "detail": <unstructured>
        },
        ...
    ]
}

code字段将是唯一的标识符,按照惯例,所有大写字母都带有下划线。该message字段将是人类可读的字符串。可选 detail字段可以包含任意json数据,以提供客户端可用来解决问题的信息。

尽管客户端可以对某些错误代码采取措施,但是注册表可能会随着时间的推移添加新的错误代码。所有客户端实现应将未知错误代码视为UNKNOWN,从而允许在不破坏API兼容性的情况下添加将来的错误代码。出于规范目的,只会添加错误代码,而不会删除。

有关所有错误代码的完整说明,请参见“错误” 部分。

API版本检查

安装在的最小端点/v2/将根据其响应状态提供版本支持信息。请求格式如下:

GET /v2/

如果200 OK返回响应,则注册表将实现V2(.1)注册表API,并且客户端可以安全地进行其他V2操作。可选地,响应可以包含有关响应主体中支持的路径的信息。客户端应准备忽略此数据。

如果401 Unauthorized返回响应,则客户端应根据“ WWW-Authenticate”标头的内容采取措施,然后重试端点。根据访问控制设置,即使此检查成功,客户端仍可能必须针对不同的资源进行身份验证。

如果返回了404 Not Found响应状态或其他意外状态,则客户端应假设注册表未实现API的V2。

当一个200 OK401 Unauthorized返回响应,“多克尔配电-API-版”报头应该被设置为“注册表/ 2.0”。客户端可能需要此标头值来确定端点是否提供此API。如果省略此标头,则客户端可能会回退到较旧的API版本。

内容摘要

此API设计在很大程度上受内容寻址能力的驱动。该设计的核心是内容可寻址标识符的概念。它通过获取字节的抗冲突哈希来唯一标识内容。通过选择通用算法,可以独立地计算和验证此类标识符。如果可以以安全的方式传达这样的标识符,则可以从不安全的来源中检索内容,独立地对其进行计算,并确定获得了正确的内容。简而言之,标识符是内容的属性。

为了消除其他概念的歧义,我们将此标识符称为摘要。甲 摘要是串行化的哈希结果,由一个的算法六角 部。该算法确定用于计算摘要的方法。的六角部分是散列的十六进制编码结果。

我们定义一个摘要字符串以匹配以下语法:

digest      := algorithm ":" hex
algorithm   := /[A-Fa-f0-9_+.-]+/
hex         := /[A-Fa-f0-9]+/

摘要的一些示例包括以下内容:

消化 描述
sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b 常见的基于sha256的摘要

尽管该算法确实允许实现多种算法,但兼容的实现应使用sha256。不鼓励在计算哈希之前对输入进行繁重的处理,以避免降低摘要的唯一性,但可以执行一些规范化以确保标识符一致。

让我们使用伪代码中的一个简单示例来演示摘要计算:

let C = 'a small string'
let B = sha256(C)
let D = 'sha256:' + EncodeHex(B)
let ID(C) = D

上面,我们将字节串C传递给了一个函数,该函数SHA256返回一个字节串B,它是的哈希值CD获取与的十六进制编码串联的算法B。然后,我们定义的标识符CID(C) 作为等于D。可以通过独立计算摘要D并将其与标识符进行比较来验证摘要ID(C)

摘要标题

为了提供http内容的验证,任何响应都可以包含 Docker-Content-Digest标头。这将包括响应中返回的目标实体的摘要。对于Blob,这是整个Blob内容。对于清单,这是没有签名内容的清单主体,也称为JWS有效负载。注意,用于摘要计算的常用规范化可能取决于内容的媒体类型,例如清单。

客户端可以选择忽略标头,也可以对其进行验证以确保内容完整性和传输安全性。当按摘要进行获取时,这是最重要的。为确保安全性,应对照用于获取内容的摘要来验证内容。有时,返回的摘要可能不同于用于发起请求的摘要。此类摘要被认为来自不同的 ,这意味着它们对于算法具有不同的值。在这种情况下,客户端可以选择验证两个域中的摘要,也可以忽略服务器的摘要。为了维护安全性,客户端必须始终对照用于获取内容的摘要来验证内容。

重要说明:如果使用摘要来获取内容,则客户端应使用用于获取内容的摘要来进行验证。标头 Docker-Content-Digest不应该受“本地”摘要的信任。

拉图像

“图像”是JSON清单和各个图层文件的组合。提取图像的过程集中在检索这两个组件上。

拉取图像的第一步是检索清单。作为参考,注册表的相关清单字段如下:

场地 描述
名称 图像名称。
标签 此版本图像的标签。
fsLayers 层描述符列表(包括摘要)
签名 用于验证清单内容的JWS

有关清单格式的更多信息,请参阅 docker / docker#8093

清单到位后,客户端必须验证签名以确保名称和层有效。确认后,客户端将使用摘要下载各个层。层以摘要形式在V2注册API中以blob形式存储。

拉图像清单

可以使用以下网址获取图片清单:

GET /v2/<name>/manifests/<reference>

namereference参数识别图像和需要。参考可以包括标签或摘要。

客户端应包括一个Accept标头,指示其支持的清单内容类型。有关清单格式及其内容类型的更多详细信息,请参见manifest-v2-1.mdmanifest-v2-2.md。在成功的响应中,Content-Type标头将指示要返回的清单类型。

404 Not Found如果注册表不知道该映像,将返回一个响应。如果映像存在并且响应成功,则将以以下格式返回映像清单(有关详细信息,请参阅 docker / docker#8093):

{
   "name": <name>,
   "tag": <tag>,
   "fsLayers": [
      {
         "blobSum": <digest>
      },
      ...
    ]
   ],
   "history": <v1 images>,
   "signature": <JWS>
}

客户端应在获取层之前验证返回的清单签名的真实性。

现有清单

可以使用以下URL检查图像清单是否存在:

HEAD /v2/<name>/manifests/<reference>

namereference参数识别图像和需要。参考可以包括标签或摘要。

404 Not Found如果注册表不知道该映像,将返回一个响应。如果映像存在并且响应成功,则响应将如下所示:

200 OK
Content-Length: <length of manifest>
Docker-Content-Digest: <digest>

拉一层

层存储在注册表的Blob部分中,以摘要为键。提取层是通过标准的http请求执行的。URL如下:

GET /v2/<name>/blobs/<digest>

对层的访问将由name存储库的门控制,但在注册表中由唯一标识digest

该端点可以发出307(<HTTP 1.1的302)重定向到另一个服务以下载该层,并且客户端应准备好处理重定向。

该端点应支持对图像层进行积极的HTTP缓存。应该包括对Etags,修改日期和其他缓存控制标头的支持。为了允许增量下载,也Range应该支持请求。

推送图像

推动图像的顺序与拉动的顺序相反。组装完图像清单后,客户端必须首先推送各个图层。将各层完全推送到注册表中后,客户端应上载已签名的清单。

以下各节介绍了该过程的每个步骤的详细信息。

推一层

所有层上载都使用两个步骤来管理上载过程。第一步开始在注册表服务中上载,返回一个URL以执行第二步。第二步使用上载URL传输实际数据。上载以POST请求开始,该请求返回一个可用于推送数据和检查上载状态的URL。

Location每个请求后,标头将用于传达上传位置。虽然在本规范中不会更改,但客户端应使用API​​返回的最新值。

开始上传

要开始该过程,应该以以下格式发出POST请求:

POST /v2/<name>/blobs/uploads/

该请求的参数是将在其下链接层的图像名称空间。涵盖了对此请求的回复。

现有层

可以通过HEAD对Blob存储区API的请求来检查层的存在。请求的格式应如下:

HEAD /v2/<name>/blobs/<digest>

如果具有指定摘要的层digest可用,则将收到200 OK响应,而没有实际的正文内容(这是根据http规范)。响应如下所示:

200 OK
Content-Length: <length of blob>
Docker-Content-Digest: <digest>

收到此响应后,客户端可以假定该层已经以给定名称在注册表中可用,并且不应该采取进一步的措施来上载该层。请注意,对于现有的注册表层,二进制摘要可能有所不同,但是可以保证摘要匹配。

上载图层

如果POST请求成功,202 Accepted将返回响应,并在Location标头中显示上传URL :

202 Accepted
Location: /v2/<name>/blobs/uploads/<uuid>
Range: bytes=0-<offset>
Content-Length: 0
Docker-Upload-UUID: <uuid>

其余的上传过程可以使用返回的网址(在Location标头中称为“上传网址”)进行。对上传网址的所有响应(无论是发送数据还是获取状态)都将采用这种格式。尽管已/v2/<name>/blobs/uploads/<uuid>Location 标头指定了URI格式(),但客户端应将其视为不透明的url,并且切勿尝试对其进行汇编。尽管该uuid参数可能是实际的UUID,但此建议不对格式施加任何约束,并且客户端绝不应施加任何约束。

如果客户端需要将本地上传状态与远程上传状态相关联,Docker-Upload-UUID则应使用标头的内容。在实现可恢复的上传时,可以使用这样的ID来密钥最后使用的位置标头。

上传进度

上传过程的进度和块协调将通过Range标头进行协调。尽管这是Range 标头的非标准用法,但在API中有大量使用类似方法的示例。对于刚刚开始的上传,例如具有1000字节图层文件的Range标头,如下所示:

Range: bytes=0-0

要获取上传状态,请向上传URL发出GET请求:

GET /v2/<name>/blobs/uploads/<uuid>
Host: <registry host>

响应将与上面类似,除了将返回204状态:

204 No Content
Location: /v2/<name>/blobs/uploads/<uuid>
Range: bytes=0-<offset>
Docker-Upload-UUID: <uuid>

请注意,HTTPRange标头字节范围是包含范围的,即使在非标准使用情况下也应遵守。

整体上传

整体上载只是具有单个块的成块上载,并且可能希望避免成块的复杂性的客户端青睐。要执行“整体”上传,只需将整个内容Blob放入所提供的URL:

PUT /v2/<name>/blobs/uploads/<uuid>?digest=<digest>
Content-Length: <size of layer>
Content-Type: application/octet-stream

<Layer Binary Data>

“摘要”参数必须包含在PUT请求中。请参阅“ 完成的上传”部分,以获取有关参数和预期响应的详细信息。

分块上传

要执行块的上载,客户端可以指定范围标头,并且仅包括图层文件的该部分:

PATCH /v2/<name>/blobs/uploads/<uuid>
Content-Length: <size of chunk>
Content-Range: <start of range>-<end of range>
Content-Type: application/octet-stream

<Layer Chunk Binary Data>

除了服务器必须按顺序接收它们之外,没有对层块拆分执行任何强制措施。服务器可以强制执行最小块大小。如果服务器不能接受该块,416 Requested Range Not Satisfiable 则将返回一个响应,并将包含Range指示当前状态的标头:

416 Requested Range Not Satisfiable
Location: /v2/<name>/blobs/uploads/<uuid>
Range: 0-<last valid range>
Content-Length: 0
Docker-Upload-UUID: <uuid>

如果收到此响应,则客户端应从“最后一个有效范围”恢复并上载后续块。416将在以下情况下返回:

  • 无效的内容范围标头格式
  • 乱序块:下一个块的范围必须在上一个响应的“最后有效范围”之后立即开始。

当接受块作为上传的一部分时,202 Accepted将返回响应,包括Range具有当前上传状态的标头:

202 Accepted
Location: /v2/<name>/blobs/uploads/<uuid>
Range: bytes=0-<offset>
Content-Length: 0
Docker-Upload-UUID: <uuid>
完成上传

为了使上传完成,客户端必须PUT 使用摘要参数在上传端点上提交请求。如果未提供,则上传不会被视为完成。最后一块的格式如下:

PUT /v2/<name>/blobs/uploads/<uuid>?digest=<digest>
Content-Length: <size of chunk>
Content-Range: <start of range>-<end of range>
Content-Type: application/octet-stream

<Last Layer Chunk Binary Data>

可选地,如果所有块都已经上传,则可以PUT发送带有digest参数和零长度正文的请求 以完成并验证上传。可以为多个“摘要”参数提供不同的摘要。服务器可能不会验证全部或全部,但是如果内容被拒绝,则必须通知客户端。

当接收到最后一个块并且该层已通过验证时,客户端将收到201 Created响应:

201 Created
Location: /v2/<name>/blobs/<digest>
Content-Length: 0
Docker-Content-Digest: <digest>

Location头将包含注册表URL访问接受层文件。的Docker-Content-Digest报头返回规范消化上传团块可从所提供的摘要不同的。大多数客户端可能会忽略该值,但是如果使用了该值,则客户端应对照上载的Blob数据来验证该值。

摘要参数

“摘要”参数被设计为不透明参数,以支持对成功传输的验证。例如,HTTP URI参数可能如下:

sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b

给定此参数,注册表将验证提供的内容是否与此摘要匹配。

取消上传

可以通过向上载终结点发出DELETE请求来取消上载。格式如下:

DELETE /v2/<name>/blobs/uploads/<uuid>

发出此请求后,上载uuid将不再有效,并且注册表服务器将转储所有中间数据。如果上传未完成,上传将超时,但是如果客户端遇到致命错误,但仍可以发出http请求,则应发出此请求。

跨存储库Blob安装

可以从客户端具有读取权限的另一个存储库中安装Blob,从而无需上载注册表已知的Blob。要发出Blob挂载而不是上载,应以以下格式发出POST请求:

POST /v2/<name>/blobs/uploads/?mount=<digest>&from=<repository name>
Content-Length: 0

如果Blob成功挂载,则客户端将收到201 Created 响应:

201 Created
Location: /v2/<name>/blobs/<digest>
Content-Length: 0
Docker-Content-Digest: <digest>

Location头将包含注册表URL访问接受层文件。的Docker-Content-Digest报头返回规范消化上传团块可从所提供的摘要不同的。大多数客户端可能会忽略该值,但是如果使用了该值,则客户端应对照上载的Blob数据来验证该值。

如果由于无效的存储库或摘要参数而导致挂载失败,则注册表将退回到标准的上载行为,并202 AcceptedLocation标头中返回带有上载URL的:

202 Accepted
Location: /v2/<name>/blobs/uploads/<uuid>
Range: bytes=0-<offset>
Content-Length: 0
Docker-Upload-UUID: <uuid>

此行为与较旧版本的注册表一致,后者无法识别存储库安装查询参数。

注意:客户端可能会发出HEAD请求以检查源存储库中是否存在Blob,以区分不支持Blob挂载的注册表和预期存储库中不存在的Blob。

失误

如果收到502、503或504错误,则客户端应假定由于临时情况下载可以继续进行,并遵守适当的重试机制。其他5xx错误应视为终端。

如果上传有问题,则将返回4xx错误,指示该问题。收到4xx响应(上面提到的416除外)后,上传将被视为失败,客户端应采取适当的措施。

请注意,上载网址将永远无法使用。如果注册表不知道上载uuid,404 Not Found则将返回响应,并且客户端必须重新启动上载过程。

删除图层

可以通过其name和将层从注册表中删除digest。可以使用以下请求格式发布删除:

DELETE /v2/<name>/blobs/<digest>

如果Blob存在并且已成功删除,则将发出以下响应:

202 Accepted
Content-Length: None

如果Blob已被删除或不存在,404 Not Found 则会发出响应。

如果删除了注册表中清单所引用的图层,则将无法解析完整的图像。

推送图像清单

上载图像的所有图层后,客户端即可上载图像清单。可以使用以下请求格式推送图像:

PUT /v2/<name>/manifests/<reference>
Content-Type: <manifest media type>

{
   "name": <name>,
   "tag": <tag>,
   "fsLayers": [
      {
         "blobSum": <digest>
      },
      ...
    ]
   ],
   "history": <v1 images>,
   "signature": <JWS>,
   ...
}

响应主体的namereference字段必须与URL中指定的匹配。该reference字段可以是“标签”或“摘要”。内容类型应匹配manifest-v2-1.mdmanifest-v2-2.md中指定的要上传清单的类型。

如果推送清单时出现问题,则将返回相关的4xx响应,并带有JSON错误消息。请参阅“ PUT清单”部分,以获取有关可能返回的错误代码的详细信息。

如果注册表不知道一层或多层,则将BLOB_UNKNOWN返回错误。的detail错误响应的字段将有一个digest字段,识别缺失的斑点。对于每个未知的Blob,都会返回一个错误。响应格式如下:

{
    "errors:" [{
            "code": "BLOB_UNKNOWN",
            "message": "blob unknown to registry",
            "detail": {
                "digest": <digest>
            }
        },
        ...
    ]
}

上市资料库

在整个API规范中都可以看到,图像存储在称为仓库的集合中,该集合由a键控 name。一个注册表实例可能包含几个存储库。可通过目录获得可用存储库的列表。

可以通过以下请求检索给定注册表的目录:

GET /v2/_catalog

响应将采用以下格式:

200 OK
Content-Type: application/json

{
  "repositories": [
    <name>,
    ...
  ]
}

请注意,响应的内容特定于注册表实现。如果提供镜像功能,某些注册管理机构可能会选择提供完整的目录输出,基于用户的访问级别对其进行限制或忽略上游结果。随后,目录列表中存储库的存在仅意味着注册表可以在请求时提供对存储库的访问。相反,欠缺的出入并 不能意味着注册表没有仓库。更简洁地说,存储库的存在仅保证存在该存储库,而不能保证它存在。

对于具有大量存储库的注册表,此响应可能会很大。如果预期会出现这种反应,则应使用分页。即使未明确请求分页,注册表也可能会限制返回的响应数量。在这种情况下,Link标头将与结果一起返回,并且可以通过跟随链接来获得后续结果,就好像最初请求了分页一样。

有关Link标题的详细信息,请参见“分页” 部分。

分页

可以通过向n请求URL添加参数来声明分页目录结果,该参数声明响应应限于n结果。开始分页流程的开始如下:

GET /v2/_catalog?n=<integer>

上面的代码指定应从结果集的开头开始,以词法排序,返回目录响应,将结果数限制为n。对此类请求的响应如下所示:

200 OK
Content-Type: application/json
Link: <<url>?n=<n from the request>&last=<last repository in response>>; rel="next"

{
  "repositories": [
    <name>,
    ...
  ]
}

上面包括了结果集中的第一 n项。要获取 下一个 n条目,可以创建一个URL,其中参数last的值为repositories[len(repositories)-1]。如果确实有更多结果,则将下一个块的URL编码在 RFC5988 Link标头中,作为“下一个”关系。Link标头的存在向客户端传达尚未返回整个结果集,必须发出另一个请求。如果标题不存在,则客户端可以假定已收到所有结果。

注意:在上面的请求模板中,请注意方括号是必需的。例如,如果url为 http://example.com/v2/_catalog?n=20&last=b,则标头的值为<http://example.com/v2/_catalog?n=20&last=b>; rel="next"。有关详细信息,请参见 RFC5988

Link线性执行结果时,兼容的客户端实现应始终使用标头值。客户端可以构造URL以在目录中向前跳过。

为了获得下一个结果集,客户端将使用描述的Link标头中编码的URL如下发出请求:

GET /v2/_catalog?n=<n from the request>&last=<last repository value from previous response>

然后应重复上述过程,直到Link不再设置标题为止。

目录结果集抽象地表示为按词法排序的列表,其中该列表中的位置可由查询字词指定last。在响应中的条目启动后,通过规定的期限last,最多n 的条目。

通过last示例进行演示时,的行为非常简单。让我们说注册表具有以下存储库:

a
b
c
d

如果值为n2,则在第一个响应上将返回abLink在响应上返回的标头将n设置为2,最后设置为b

Link: <<url>?n=2&last=b>; rel="next"

然后,客户端可以从Link 标头中发出具有上述值的请求,并接收值cd。请注意n,根据服务器的实现,可能在倒数第二个响应上更改或完全省略。

列出图片标签

可能有必要列出给定存储库下的所有标签。可以使用以下请求来检索图像存储库的标签:

GET /v2/<name>/tags/list

响应将采用以下格式:

200 OK
Content-Type: application/json

{
    "name": <name>,
    "tags": [
        <tag>,
        ...
    ]
}

对于带有大量标签的存储库,此响应可能会很大。如果期望得到这样的响应,则应使用分页。

分页

通过将适当的参数添加到上述请求URL中,可以检索分页的标记结果。标签分页的行为与为目录分页指定的行为相同。我们涵盖了一个简单的流程以突出显示所有差异。

开始分页流程可能如下所示:

GET /v2/<name>/tags/list?n=<integer>

上面的代码指定应从结果集的开头开始按词法排序返回标签响应,并将结果数限制为n。对此类请求的响应如下所示:

200 OK
Content-Type: application/json
Link: <<url>?n=<n from the request>&last=<last tag value from previous response>>; rel="next"

{
  "name": <name>,
  "tags": [
    <tag>,
    ...
  ]
}

为了获得下一个结果集,客户端将使用RFC5988 Link 标头中编码的值按以下方式发出请求:

GET /v2/<name>/tags/list?n=<n from the request>&last=<last tag value from previous response>

然后应重复上述过程,直到Link在响应中不再设置标题为止。last参数的行为,提供的响应结果,Link标题的词法排序和编码与目录分页的行为相同。

删除影像

图像可以通过其name和从注册表中删除reference。可以使用以下请求格式发布删除:

DELETE /v2/<name>/manifests/<reference>

对于删除,reference 必须是摘要,否则删除将失败。如果图像存在并且已成功删除,则将发出以下响应:

202 Accepted
Content-Length: None

如果图像已被删除或不存在,404 Not Found 则会发出响应。

注意 当从注册表2.3版删除清单或更高版本,下面的头时必须使用HEADGET-ing清单,以获得正确的消化删除:

Accept: application/vnd.docker.distribution.manifest.v2+json

有关更多详细信息,请参见:compatible.md

细节

注意:此部分仍在建设中。为了实现目的,如果以下任何细节与上述请求流程不同,则应更正以下部分。当它们匹配时,应删除此注释。

本节将详细介绍端点的行为,并按路线和实体进行组织。涵盖了请求和响应的所有方面,包括标题,参数和主体格式。列举了请求及其相应的响应(包括成功和失败)的示例。

注意:端点详细信息的各节安排有一个示例请求,对该请求的描述以及有关该请求的信息。

下表列出了方法和URI的列表:

方法 小路 实体 描述
得到 /v2/ 根据 检查端点是否实现了Docker Registry API V2。
得到 /v2/<name>/tags/list 标签 在标识的存储库下获取标签name
得到 /v2/<name>/manifests/<reference> 显现 获取由标签或摘要标识的清单,name以及reference在哪里reference可以是标签或摘要。一个HEAD请求,也可以发送到此端点,以获取资源信息,而不接收的所有数据。
/v2/<name>/manifests/<reference> 显现 将清单所标识的清单放在哪里,name并可以在reference其中reference放置标签或摘要。
删除 /v2/<name>/manifests/<reference> 显现 删除由name和标识的清单reference。请注意,清单只能由删除digest
得到 /v2/<name>/blobs/<digest> 斑点 从标识的注册表中检索Blob digest。一个HEAD请求,也可以发送到此端点,以获取资源信息,而不接收的所有数据。
删除 /v2/<name>/blobs/<digest> 斑点 删除由name和标识的Blobdigest
邮政 /v2/<name>/blobs/uploads/ 启动Blob上传 启动可恢复的Blob上传。如果成功,将提供一个上载位置以完成上载。(可选)如果digest存在该参数,则请求正文将用于在单个请求中完成上载。
得到 /v2/<name>/blobs/uploads/<uuid> Blob上传 检索由标识的上传状态uuid。该端点的主要目的是解决可恢复上载的当前状态。
修补 /v2/<name>/blobs/uploads/<uuid> Blob上传 上载用于指定上载的数据块。
/v2/<name>/blobs/uploads/<uuid> Blob上传 完成由指定的上传uuid,可以选择将正文附加为最后的块。
删除 /v2/<name>/blobs/uploads/<uuid> Blob上传 取消未完成的上传过程,释放关联的资源。如果未调用此选项,则未完成的上传最终将超时。
得到 /v2/_catalog 目录 检索注册表中可用的存储库的排序的json列表。

以下各节介绍了每个端点的详细信息。

失误

下表列出了通过API遇到的错误代码:

代码 信息 描述
BLOB_UNKNOWN 注册表未知的Blob 当指定存储库中的注册表未知Blob时,可能会返回此错误。可以使用标准get或清单在上载期间引用未知图层的方式返回此值。
BLOB_UPLOAD_INVALID Blob上传无效 Blob上传遇到错误,无法继续进行。
BLOB_UPLOAD_UNKNOWN Blob上载到注册表未知 如果Blob上传已取消或从未启动,则可能会返回此错误代码。
DIGEST_INVALID 提供的摘要与上传的内容不匹配 上载Blob时,注册表将检查内容是否与客户端提供的摘要匹配。错误可能包括带有键“摘要”的详细结构,包括无效的摘要字符串。当清单包含无效的图层摘要时,也可能会返回此错误。
MANIFEST_BLOB_UNKNOWN 注册表未知的Blob 注册表不知道清单Blob时,可能会返回此错误。
MANIFEST_INVALID 明显无效 在上载过程中,清单经过多次检查以确保有效性。如果这些检查失败,则可能会返回此错误,除非包含更具体的错误。详细信息将包含验证失败的信息。
MANIFEST_UNKNOWN 表现未知 当存储库未知由名称和标记标识的清单时,将返回此错误。
MANIFEST_UNVERIFIED 清单签名验证失败 在清单上传期间,如果清单未通过签名验证,则将返回此错误。
NAME_INVALID 无效的存储库名称 在清单验证或任何API操作期间遇到无效的存储库名称。
NAME_UNKNOWN 注册表不知道的存储库名称 如果注册表中不知道操作期间使用的名称,则返回此值。
SIZE_INVALID 提供的长度与内容长度不匹配 上载图层时,将根据上载的内容检查提供的大小。如果它们不匹配,将返回此错误。
TAG_INVALID 清单标签与URI不匹配 在清单上传期间,如果清单中的标记与uri标记不匹配,则将返回此错误。
UNAUTHORIZED 需要认证 访问控制器无法验证客户端。通常,它会伴随一个Www-Authenticate HTTP响应标头,指示如何进行身份验证。
DENIED 请求的对资源的访问被拒绝 访问控制器拒绝访问该资源上的操作。
UNSUPPORTED 不支持该操作。 由于缺少实现或无效的参数集,因此不支持该操作。

根据

基本V2 API路由。通常,它可以用于轻量级版本检查和验证注册表身份验证。

GET基地

检查端点是否实现了Docker Registry API V2。

GET /v2/
Host: <registry host>
Authorization: <scheme> <token>

应在请求中指定以下参数:

名称 种类 描述
Host 标头 标准HTTP主机标头。应该设置为注册表主机。
Authorization 标头 符合RFC7235的授权标头。
成功时:可以
200 OK

该API实现了V2协议,并且可以访问。

失败时:找不到
404 Not Found

注册表未实现V2 API。

失败时:需要身份验证
401 Unauthorized
WWW-Authenticate: <scheme> realm="<realm>", ..."
Content-Length: <length>
Content-Type: application/json; charset=utf-8

{
	"errors:" [
	    {
            "code": <error code>,
            "message": "<error message>",
            "detail": ...
        },
        ...
    ]
}

客户端未通过身份验证。

以下标头将在响应中返回:

名称 描述
WWW-Authenticate 符合RFC7235的身份验证质询标头。
Content-Length JSON响应主体的长度。

下面列举了可能包含在响应正文中的错误代码:

代码 信息 描述
UNAUTHORIZED 需要认证 访问控制器无法验证客户端。通常,它会伴随一个Www-Authenticate HTTP响应标头,指示如何进行身份验证。
失败时:请求过多
429 Too Many Requests
Content-Length: <length>
Content-Type: application/json; charset=utf-8

{
	"errors:" [
	    {
            "code": <error code>,
            "message": "<error message>",
            "detail": ...
        },
        ...
    ]
}

客户端在一个时间间隔内发出了太多请求。

以下标头将在响应中返回:

名称 描述
Content-Length JSON响应主体的长度。

下面列举了可能包含在响应正文中的错误代码:

代码 信息 描述
TOOMANYREQUESTS 太多要求 当客户尝试联系服务太多次时返回

标签

检索有关标签的信息。