通过 HTTP API 在 Docker 集线器上列出 Docker 图像的标签
Listing the tags of a Docker image on a Docker hub through the HTTP API
我想通过其 HTTP 接口列出 Docker 图片官方 Docker 集线器的标签,但我有点困惑。因为它们似乎有两个版本:
- https://docs.docker.com/v1.6/reference/api/registry_api/
- https://docs.docker.com/v1.6/registry/spec/api/
我设法通过向此端点发送 GET 请求来获取它们:https://index.docker.io/v1/repositories/{my-namespace}/{my-repository}/tags
以及基本身份验证凭据。
我不确定其中是否有正确的,但我应该使用哪个?
Docker 对注册表进行了巨大的重构:registry v2.0.
随着这个全新版本的出现,带来了新的身份验证系统,因此 v1.0 的基本身份验证将不再有效。
您可以在此处找到有关 v2.0 身份验证的更多详细信息:https://docs.docker.com/v1.6/registry/spec/auth/token/
由于 v1.0 已弃用,您应该继续使用注册表 v2.0。
这里有一个 Bash 脚本可以做到这一点。将其保存到名为 docker-hub-tags-list 的文件中,然后 运行 如下所示:
docker-hub-tags-list markriggins/todowrangler
但您需要先通过docker login
登录。并且您需要安装 JSON 工具 http://trentm.com/json/,这是一个非常酷的工具,用于在命令行上解析 JSON。
#!/usr/bin/env bash
REPOSITORY=${REPOSITORY:-}
REGISTRY=${REGISTRY:-docker.io}
#
# Docker funcs
#
d__docker_relative_repository_name_from_URL() {
# Given $REGISTRY/repo/path:tag, return the repo/path
set +o pipefail
echo ${1-} | sed -e "s|^$REGISTRY/||" | cut -d: -f1
}
d___version_sort() {
# Read stdin, sort by version number descending, and write stdout
# It assumes X.Y.Z version numbers
# This will sort tags like pr-3001, pr-3002 to the END of the list
# and tags like 2.1.4 BEFORE 2.1.4-gitsha
sort -s -t- -k 2,2nr | sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
}
d__basic_auth() {
#
# Read basic authentication credentials from `docker login`
#
cat ~/.docker/config.json | json '.auths["https://index.docker.io/v1/"].auth'
}
d__registry__tags_list() {
# Return a list of available tags for the given repository sorted
# by version number, descending
#
# Get tags list from dockerhub using the v2 API and an auth.docker token
local rel_repository=$(d__docker_relative_repository_name_from_URL )
[ -z "$rel_repository" ] && return
local TOKEN=$(curl -s -H "Authorization: Basic $(d__basic_auth)" \
-H 'Accept: application/json' \
"https://auth.docker.io/token?service=registry.docker.io&scope=repository:$rel_repository:pull" | json .token)
curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
"https://index.docker.io/v2/$rel_repository/tags/list" |
json .tags |
json -a |
d___version_sort
}
d__registry__tags_list $REPOSITORY
Docker V2 API
更新
Docker V2 API 需要具有适当声明的 OAuth 不记名令牌。在我看来,官方文档在这个话题上相当含糊。为了让其他人不会经历与我相同的痛苦,我提供以下 docker-tags
功能。
最新版本的docker-tags
可以在我的GitHubGist : "List Docker Image Tags using bash"中找到。
docker-tags 函数依赖于 jq。如果您正在玩 JSON,您可能已经拥有它了。
#!/usr/bin/env bash
docker-tags() {
arr=("$@")
for item in "${arr[@]}";
do
tokenUri="https://auth.docker.io/token"
data=("service=registry.docker.io" "scope=repository:$item:pull")
token="$(curl --silent --get --data-urlencode ${data[0]} --data-urlencode ${data[1]} $tokenUri | jq --raw-output '.token')"
listUri="https://registry-1.docker.io/v2/$item/tags/list"
authz="Authorization: Bearer $token"
result="$(curl --silent --get -H "Accept: application/json" -H "Authorization: Bearer $token" $listUri | jq --raw-output '.')"
echo $result
done
}
例子
docker-tags "microsoft/nanoserver" "microsoft/dotnet" "library/mongo" "library/redis"
诚然,docker-tags
做出了几个假设。具体来说,OAuth 请求参数大多是硬编码的。更雄心勃勃的实施将向注册表发出未经身份验证的请求,并从未经身份验证的响应中派生 OAuth 参数。
私有图像存储库,v2 API
与私有和 public 存储库一起使用的版本,用 vanilla Bourne shell(包括但不限于 Bash)编写,并使用 v2 API,住在 https://gist.github.com/nealey/86da928cdb5c21a4edc1be2ba7b845e3
你可以运行这样:
$ docker-tags.sh alpine
$ docker-tags.sh ceph/daemon
$ docker-tags.sh quay.io/coreos/dnsmasq
它列出所有版本,每行一个。
#! /bin/sh
image=""; shift
if [ -z "$image" ] || [ "$image" == "--help" ]; then
echo "Usage: [=11=] IMAGE"
echo
echo "Prints all tags associated with IMAGE in a docker repository"
exit 1
fi
case "$image" in
*/*/*)
host=${image%%/*/*}
path=${image#*/}
;;
*/*)
host=index.docker.io
path=$image
;;
*)
host=index.docker.io
path=library/$image
;;
esac
tags_uri=https://$host/v2/$path/tags/list
##
## Figure out who hands out tokens by doing an unauthenticated request
##
extract () {
# XXX: This can't handle values with commas in them
echo -n "" | awk -v f="" 'BEGIN {RS=","; FS="=\"|\"$";} ( == f) { print ; }'
}
auth=$(curl --silent -I $tags_uri | sed -n 's/^Www-Authenticate: Bearer //p' | tr -d '\r')
if [ -n "$auth" ]; then
realm=$(extract realm "$auth")
service=$(extract service "$auth")
scope=$(extract scope "$auth")
## Now fetch a token
token=$(curl --silent --get --data-urlencode "service=$service" --data-urlencode "scope=$scope" $realm | jq -r '.token')
auth_header="Authorization: Bearer $token"
fi
## Finally, list versions
curl -s --header "$auth_header" "$tags_uri" | jq -r '.tags[]'
我来晚了,我搜索这个问题是为了列出同一图像的所有标签(理解摘要),不幸的是,大多数答案只是关于显示推送的任何图像摘要的所有可用标签。
手头的案例,对于开放 jdk 相同的图像摘要通常被标记多次:
{
"sha256:518f6c2137b7463272cb1f52488e914b913b92bfe0783acb821c216987959971": [
"11",
"11-buster",
"11-jdk",
"11-jdk-buster",
"11.0",
"11.0-buster",
"11.0-jdk",
"11.0-jdk-buster",
"11.0.8",
"11.0.8-buster",
"11.0.8-jdk",
"11.0.8-jdk-buster"
]
},
我找不到相关的 API v2,似乎 api 公开了标签,但没有详细信息,否则您需要列出每个 blob 清单以通过以下方式获取匹配的摘要响应 header Docker-Content-Digest
。我除非在有很多标签的情况下错过了对我的用例不可用的东西,所以我只是使用 regular dockerhub API 来获取所有标签和它们的详细信息和组这些标签由图像摘要。
(
url="https://registry.hub.docker.com/v2/repositories/library/openjdk/tags/?page_size=100" ;
while [ -n "$url" ]; do
>&2 echo -n ".";
content="$(curl -s "$url")";
url=$(jq -r '.next // empty' <<< "${content}");
echo "$content";
done;
>&2 echo;
) | jq -s '[.[].results[]]' \
| jq 'map({tag: .name, digest: .images[].digest}) | unique | group_by(.digest) | map(select(.[].digest) | {(.[0].digest): [.[].tag]})' \
> openjdk-tags.json
我已将其作为脚本发布在此gist,如有任何评论或建议,我们将不胜感激。
感谢 Neale Picket 的脚本。
它不适用于私人存储库,所以我对其进行了一些编辑(并且还修复了 headers 检测时区分大小写的问题)
这个在一开始就询问你的 Dockerhub 用户和密码,并用它来向 Dockehuv 发出和验证请求 API。
要点:https://gist.github.com/juanlb/b959354cc289dd9962e9f57dee4ac063
我想通过其 HTTP 接口列出 Docker 图片官方 Docker 集线器的标签,但我有点困惑。因为它们似乎有两个版本:
- https://docs.docker.com/v1.6/reference/api/registry_api/
- https://docs.docker.com/v1.6/registry/spec/api/
我设法通过向此端点发送 GET 请求来获取它们:https://index.docker.io/v1/repositories/{my-namespace}/{my-repository}/tags
以及基本身份验证凭据。
我不确定其中是否有正确的,但我应该使用哪个?
Docker 对注册表进行了巨大的重构:registry v2.0.
随着这个全新版本的出现,带来了新的身份验证系统,因此 v1.0 的基本身份验证将不再有效。
您可以在此处找到有关 v2.0 身份验证的更多详细信息:https://docs.docker.com/v1.6/registry/spec/auth/token/
由于 v1.0 已弃用,您应该继续使用注册表 v2.0。
这里有一个 Bash 脚本可以做到这一点。将其保存到名为 docker-hub-tags-list 的文件中,然后 运行 如下所示:
docker-hub-tags-list markriggins/todowrangler
但您需要先通过docker login
登录。并且您需要安装 JSON 工具 http://trentm.com/json/,这是一个非常酷的工具,用于在命令行上解析 JSON。
#!/usr/bin/env bash
REPOSITORY=${REPOSITORY:-}
REGISTRY=${REGISTRY:-docker.io}
#
# Docker funcs
#
d__docker_relative_repository_name_from_URL() {
# Given $REGISTRY/repo/path:tag, return the repo/path
set +o pipefail
echo ${1-} | sed -e "s|^$REGISTRY/||" | cut -d: -f1
}
d___version_sort() {
# Read stdin, sort by version number descending, and write stdout
# It assumes X.Y.Z version numbers
# This will sort tags like pr-3001, pr-3002 to the END of the list
# and tags like 2.1.4 BEFORE 2.1.4-gitsha
sort -s -t- -k 2,2nr | sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
}
d__basic_auth() {
#
# Read basic authentication credentials from `docker login`
#
cat ~/.docker/config.json | json '.auths["https://index.docker.io/v1/"].auth'
}
d__registry__tags_list() {
# Return a list of available tags for the given repository sorted
# by version number, descending
#
# Get tags list from dockerhub using the v2 API and an auth.docker token
local rel_repository=$(d__docker_relative_repository_name_from_URL )
[ -z "$rel_repository" ] && return
local TOKEN=$(curl -s -H "Authorization: Basic $(d__basic_auth)" \
-H 'Accept: application/json' \
"https://auth.docker.io/token?service=registry.docker.io&scope=repository:$rel_repository:pull" | json .token)
curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
"https://index.docker.io/v2/$rel_repository/tags/list" |
json .tags |
json -a |
d___version_sort
}
d__registry__tags_list $REPOSITORY
Docker V2 API
更新Docker V2 API 需要具有适当声明的 OAuth 不记名令牌。在我看来,官方文档在这个话题上相当含糊。为了让其他人不会经历与我相同的痛苦,我提供以下 docker-tags
功能。
最新版本的docker-tags
可以在我的GitHubGist : "List Docker Image Tags using bash"中找到。
docker-tags 函数依赖于 jq。如果您正在玩 JSON,您可能已经拥有它了。
#!/usr/bin/env bash
docker-tags() {
arr=("$@")
for item in "${arr[@]}";
do
tokenUri="https://auth.docker.io/token"
data=("service=registry.docker.io" "scope=repository:$item:pull")
token="$(curl --silent --get --data-urlencode ${data[0]} --data-urlencode ${data[1]} $tokenUri | jq --raw-output '.token')"
listUri="https://registry-1.docker.io/v2/$item/tags/list"
authz="Authorization: Bearer $token"
result="$(curl --silent --get -H "Accept: application/json" -H "Authorization: Bearer $token" $listUri | jq --raw-output '.')"
echo $result
done
}
例子
docker-tags "microsoft/nanoserver" "microsoft/dotnet" "library/mongo" "library/redis"
诚然,docker-tags
做出了几个假设。具体来说,OAuth 请求参数大多是硬编码的。更雄心勃勃的实施将向注册表发出未经身份验证的请求,并从未经身份验证的响应中派生 OAuth 参数。
私有图像存储库,v2 API
与私有和 public 存储库一起使用的版本,用 vanilla Bourne shell(包括但不限于 Bash)编写,并使用 v2 API,住在 https://gist.github.com/nealey/86da928cdb5c21a4edc1be2ba7b845e3
你可以运行这样:
$ docker-tags.sh alpine
$ docker-tags.sh ceph/daemon
$ docker-tags.sh quay.io/coreos/dnsmasq
它列出所有版本,每行一个。
#! /bin/sh
image=""; shift
if [ -z "$image" ] || [ "$image" == "--help" ]; then
echo "Usage: [=11=] IMAGE"
echo
echo "Prints all tags associated with IMAGE in a docker repository"
exit 1
fi
case "$image" in
*/*/*)
host=${image%%/*/*}
path=${image#*/}
;;
*/*)
host=index.docker.io
path=$image
;;
*)
host=index.docker.io
path=library/$image
;;
esac
tags_uri=https://$host/v2/$path/tags/list
##
## Figure out who hands out tokens by doing an unauthenticated request
##
extract () {
# XXX: This can't handle values with commas in them
echo -n "" | awk -v f="" 'BEGIN {RS=","; FS="=\"|\"$";} ( == f) { print ; }'
}
auth=$(curl --silent -I $tags_uri | sed -n 's/^Www-Authenticate: Bearer //p' | tr -d '\r')
if [ -n "$auth" ]; then
realm=$(extract realm "$auth")
service=$(extract service "$auth")
scope=$(extract scope "$auth")
## Now fetch a token
token=$(curl --silent --get --data-urlencode "service=$service" --data-urlencode "scope=$scope" $realm | jq -r '.token')
auth_header="Authorization: Bearer $token"
fi
## Finally, list versions
curl -s --header "$auth_header" "$tags_uri" | jq -r '.tags[]'
我来晚了,我搜索这个问题是为了列出同一图像的所有标签(理解摘要),不幸的是,大多数答案只是关于显示推送的任何图像摘要的所有可用标签。
手头的案例,对于开放 jdk 相同的图像摘要通常被标记多次:
{
"sha256:518f6c2137b7463272cb1f52488e914b913b92bfe0783acb821c216987959971": [
"11",
"11-buster",
"11-jdk",
"11-jdk-buster",
"11.0",
"11.0-buster",
"11.0-jdk",
"11.0-jdk-buster",
"11.0.8",
"11.0.8-buster",
"11.0.8-jdk",
"11.0.8-jdk-buster"
]
},
我找不到相关的 API v2,似乎 api 公开了标签,但没有详细信息,否则您需要列出每个 blob 清单以通过以下方式获取匹配的摘要响应 header Docker-Content-Digest
。我除非在有很多标签的情况下错过了对我的用例不可用的东西,所以我只是使用 regular dockerhub API 来获取所有标签和它们的详细信息和组这些标签由图像摘要。
(
url="https://registry.hub.docker.com/v2/repositories/library/openjdk/tags/?page_size=100" ;
while [ -n "$url" ]; do
>&2 echo -n ".";
content="$(curl -s "$url")";
url=$(jq -r '.next // empty' <<< "${content}");
echo "$content";
done;
>&2 echo;
) | jq -s '[.[].results[]]' \
| jq 'map({tag: .name, digest: .images[].digest}) | unique | group_by(.digest) | map(select(.[].digest) | {(.[0].digest): [.[].tag]})' \
> openjdk-tags.json
我已将其作为脚本发布在此gist,如有任何评论或建议,我们将不胜感激。
感谢 Neale Picket 的脚本。 它不适用于私人存储库,所以我对其进行了一些编辑(并且还修复了 headers 检测时区分大小写的问题)
这个在一开始就询问你的 Dockerhub 用户和密码,并用它来向 Dockehuv 发出和验证请求 API。
要点:https://gist.github.com/juanlb/b959354cc289dd9962e9f57dee4ac063