如何使用 Docker Registry HTTP API V2 获取 docker 注册表中所有存储库的列表?

Posted

技术标签:

【中文标题】如何使用 Docker Registry HTTP API V2 获取 docker 注册表中所有存储库的列表?【英文标题】:How can I use Docker Registry HTTP API V2 to obtain a list of all repositories in a docker registry? 【发布时间】:2019-10-05 04:21:09 【问题描述】:

一个与我合作的外部组织允许我访问一个私有的(受身份验证令牌保护的)docker 注册表,最终我希望能够使用 docker 的 HTTP API V2 查询这个注册表,以获得一个列表注册表中可用的所有存储库和/或图像。

但在此之前,我首先想获得一些基本练习,即在 Docker Hub 等公共注册表上构建这些类型的 API 查询。所以我继续在 Docker Hub 上使用用户名和密码 registered myself,还查阅了 API V2 文档,其中指出可以请求 API version check:

GET /v2/

或请求list of repositories:

GET /v2/_catalog

使用 curl 以及我用来注册 Docker Hub 帐户的用户名和密码,我尝试在命令行构造一个 GET 请求:

stachyra> curl -u stachyra:<my_password> -X GET https://index.docker.io/v2/
"errors":["code":"UNAUTHORIZED","message":"authentication required","detail":null]
stachyra> curl -u stachyra:<my_password> -X GET https://index.docker.io/v2/_catalog
"errors":["code":"UNAUTHORIZED","message":"authentication required","detail":["Type":"registry","Class":"","Name":"catalog","Action":"*"]]

当然,我用我的实际帐户密码代替了&lt;my_password&gt;

我一直期待从该查询中得到的响应是一条巨大的 json 消息,其中列出了数千个存储库名称,但似乎 API 拒绝了我的 Docker Hub 凭据。

问题 1: 我是否有正确的 docker hub 注册表 URL (index.docker.io)? (我首先根据命令行工具docker info返回的状态信息做出了这个假设,所以我有充分的理由认为它是正确的。)

问题 2: 假设我的注册服务本身的 URL 正确,为什么我的查询会返回“未授权”错误代码?当我尝试通过网络登录 hub.docker.com 时,我的帐户凭据工作正常,那么这两种情况有什么区别?

【问题讨论】:

【参考方案1】:

首先,Docker是一个协议,DockerHub是实现了Docker协议但不限于此的产品。

hub.docker.com 拥有丰富的 DockerHub 特有的APIs。

index.docker.io 是 DockerHub 的通用 Docker API V2 实现,用于支持多个 Docker 注册表的大多数客户端。

DockerHub 实现了通用的 Docker HTTP API V2,但它来自 generic API set 的 doesn't implement _catalog API。

DockerHub Docker API V2 用法

为了使用 Docker V2 API,需要生成 JWT 身份验证令牌,并且该令牌必须用作 DockerHub 调用中的 Bearer 令牌index.docker.io

当您像这样使用 DockerHub API 时:

https://index.docker.io/v2/library/alpine/tags/list 它返回 401,

寻找响应头

www-authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:library/alpine:pull",error="invalid_token"

这意味着,您需要显式调用

https://auth.docker.io/token?service=registry.docker.io&amp;scope=repository:library/alpine:pull

这将为您提供可以在原始index.docker.io 请求中使用的不记名令牌。

https://auth.docker.io/token 无需任何身份验证令牌即可工作,但仅适用于公共存储库。

如果你想访问一个私有仓库,你需要在请求中添加基本的身份验证头。

curl -u username:password https://auth.docker.io/token?service=registry.docker.io&amp;scope=repository:&lt;repo&gt;:pull

注意:auth.docker.io 无论如何都会生成一个令牌,即使请求无效(信用或范围或任何东西)。要验证令牌,如果将令牌放入 jwt.io,您应该会在 payload 中看到 access 字段,其中包含请求的范围引用。

【讨论】:

【参考方案2】:

这是一个从注册表读取存储库的示例程序。我用它作为 Docker Hub 的学习辅助工具。

#!/bin/bash

set -e

# set username and password
UNAME="username"
UPASS="password"

# get token to be able to talk to Docker Hub
TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '"username": "'$UNAME'", "password": "'$UPASS'"' https://hub.docker.com/v2/users/login/ | jq -r .token)

# get list of repos for that user account
REPO_LIST=$(curl -s -H "Authorization: JWT $TOKEN" 
https://hub.docker.com/v2/repositories/$UNAME/?page_size=10000 | jq -r '.results|.[]|.name')

# build a list of all images & tags
for i in $REPO_LIST
do
  # get tags for repo
  IMAGE_TAGS=$(curl -s -H "Authorization: JWT $TOKEN" 
  https://hub.docker.com/v2/repositories/$UNAME/$i/tags/?page_size=10000 | jq -r '.results|.[]|.name')

  # build a list of images from tags
  for j in $IMAGE_TAGS
  do
    # add each tag to list
    FULL_IMAGE_LIST="$FULL_IMAGE_LIST $UNAME/$i:$j"
  done
done

# output list of all docker images
for i in $FULL_IMAGE_LIST
do
  echo $i
done

(来自描述如何使用 API 的 article on Docker site。)

本质上...

获取令牌 将令牌作为标头 Authorization: JWT &lt;token&gt; 与您进行的任何 API 调用一起传递 您要用于列出存储库的 api 调用是 https://hub.docker.com/v2/repositories/&lt;username&gt;/

【讨论】:

很好的解释,谢谢!我注意到默认情况下它只能访问公共存储库(如curl -s -H "Authorization: TOKEN" https://hub.docker.com/v2/repositories/USERNAME/curl -s -H "Authorization: TOKEN" https://hub.docker.com/v2/repositories/USERNAME/?is_private=true 确实输出相同的结果)。不幸的是,这个参数?is_private=true 没有输出:你知道这是否可能吗?问候! 对不起,我认为这个程序不是很健壮,它只是一个例子。它仅列出具有标签的存储库(如果您只是测试,则可能没有)。我刚刚尝试过,默认情况下它会返回所有 repos。如果你添加了?is_private=true,那么你只会得到私有的,同样如果你通过false。在程序中添加一些打印,使其超出i(repo)和j(tag)的值,你应该会看到你所期望的。 感谢您的快速回复!不幸的是,在我的情况下,在没有此参数或值为 false 的情况下使用此 URL 有效(我唯一的公共 repo 输出),但是当使用值为 true 的此参数时,我的私有 repos 输出都没有我只看到"count": 0, "next": null, "previous": null, "results": [] 我仍然会尝试在这里挖,让你知道我是否找到了什么。祝你有美好的一天!【参考方案3】:

This site 说我们不能:(

Dockerhub 混合托管公共和私有存储库,但不 公开一个目录端点以编程方式列出它们。

【讨论】:

非 Hub 注册表呢? 这里的答案说在 Registry V2 中是可能的:***.com/questions/31251356/… 我能够在非中心注册表上使用适当的 V2 来做到这一点。

以上是关于如何使用 Docker Registry HTTP API V2 获取 docker 注册表中所有存储库的列表?的主要内容,如果未能解决你的问题,请参考以下文章

docker registry使用http协议

docker registry使用http协议

docker registry使用http协议

如何搭建及使用docker registry

Docker--------registry私有仓库搭建 [ Http ]

Docker--------Harbor registry私有仓库搭建 [ Http ]