如何使用 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":"*"]]
当然,我用我的实际帐户密码代替了<my_password>
。
我一直期待从该查询中得到的响应是一条巨大的 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&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&scope=repository:<repo>: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 <token>
与您进行的任何 API 调用一起传递
您要用于列出存储库的 api 调用是 https://hub.docker.com/v2/repositories/<username>/
【讨论】:
很好的解释,谢谢!我注意到默认情况下它只能访问公共存储库(如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 注册表中所有存储库的列表?的主要内容,如果未能解决你的问题,请参考以下文章