如何在Docker命令行上的Docker注册表中找到具有特定标签的Docker映像



我尝试为Docker图像找到一个特定的标记。我如何在命令行上完成它?我想避免下载所有的图像,然后删除不需要的。

在Ubuntu官方版本https://registry.hub.docker.com/_/ubuntu/中,有几个标签(release for it),而当我在命令行中搜索它时,

user@ubuntu:~$ docker search ubuntu | grep ^ubuntu
ubuntu              Official Ubuntu base image                          354
ubuntu-upstart      Upstart is an event-based replacement for ...   7
ubuntufan/ping                                                0
ubuntu-debootstrap                                                   0

也在命令行search https://docs.docker.com/engine/reference/commandline/search/的帮助下,不知道它是如何工作的?

docker search命令中是否可能?

如果我使用一个raw命令通过Docker注册表API搜索,那么信息可以被获取:

   $ curl https://registry.hub.docker.com//v1/repositories/ubuntu/tags | python -mjson.tool
   [
    {
        "layer": "ef83896b",
        "name": "latest"
    },
    .....
    {
        "layer": "463ff6be",
        "name": "raring"
    },
    {
        "layer": "195eb90b",
        "name": "saucy"
    },
    {
        "layer": "ef83896b",
        "name": "trusty"
    }
]

使用CoreOS时,可以使用jq解析JSON数据

就像你之前做的那样,看library/centos:

$ curl -s -S 'https://registry.hub.docker.com/v2/repositories/library/centos/tags/' | jq '."results"[]["name"]' |sort
"6"
"6.7"
"centos5"
"centos5.11"
"centos6"
"centos6.6"
"centos6.7"
"centos7.0.1406"
"centos7.1.1503"
"latest"

现在可以使用cleaner v2 API,这就是我在示例中使用的API。我将构建一个简单的脚本docker_remote_tags:

#!/usr/bin/bash
curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$@/tags/" | jq '."results"[]["name"]' |sort

使:

$ ./docker_remote_tags library/centos
"6"
"6.7"
"centos5"
"centos5.11"
"centos6"
"centos6.6"
"centos6.7"
"centos7.0.1406"
"centos7.1.1503"
"latest"
参考:

jq: https://stedolan.github.io/jq/| apt-get install jq

我不喜欢上面的任何解决方案,因为A)它们需要外部库,我没有,也不想安装。B)我没有拿到所有的页码。

Docker API限制每个请求最多100个条目。这将循环遍历每个"next"条目并获取它们全部(对于Python,它是七页;其他可能是或多或少……这取决于)

如果你真的想自己发垃圾邮件,从最后一行删除| cut -d '-' -f 1,你就会看到所有的东西。

url=https://registry.hub.docker.com/v2/repositories/library/redis/tags/?page_size=100 `# Initial url` ; 
( 
  while [ ! -z $url ]; do `# Keep looping until the variable url is empty` 
    >&2 echo -n "." `# Every iteration of the loop prints out a single dot to show progress as it got through all the pages (this is inline dot)` ; 
    content=$(curl -s $url | python -c 'import sys, json; data = json.load(sys.stdin); print(data.get("next", "") or ""); print("n".join([x["name"] for x in data["results"]]))') `# Curl the URL and pipe the output to Python. Python will parse the JSON and print the very first line as the next URL (it will leave it blank if there are no more pages) then continue to loop over the results extracting only the name; all will be stored in a variable called content` ; 
    url=$(echo "$content" | head -n 1) `# Let's get the first line of content which contains the next URL for the loop to continue` ; 
    echo "$content" | tail -n +2 `# Print the content without the first line (yes +2 is counter intuitive)` ; 
  done; 
  >&2 echo `# Finally break the line of dots` ; 
) | cut -d '-' -f 1 | sort --version-sort | uniq;
样本输出:

$ url=https://registry.hub.docker.com/v2/repositories/library/redis/tags/?page_size=100 `#initial url` ; 
> ( 
>   while [ ! -z $url ]; do `#Keep looping until the variable url is empty` 
>     >&2 echo -n "." `#Every iteration of the loop prints out a single dot to show progress as it got through all the pages (this is inline dot)` ; 
>     content=$(curl -s $url | python -c 'import sys, json; data = json.load(sys.stdin); print(data.get("next", "") or ""); print("n".join([x["name"] for x in data["results"]]))') `# Curl the URL and pipe the JSON to Python. Python will parse the JSON and print the very first line as the next URL (it will leave it blank if there are no more pages) then continue to loop over the results extracting only the name; all will be store in a variable called content` ; 
>     url=$(echo "$content" | head -n 1) `#Let's get the first line of content which contains the next URL for the loop to continue` ; 
>     echo "$content" | tail -n +2 `#Print the content with out the first line (yes +2 is counter intuitive)` ; 
>   done; 
>   >&2 echo `#Finally break the line of dots` ; 
> ) | cut -d '-' -f 1 | sort --version-sort | uniq;
...
2
2.6
2.6.17
2.8
2.8.6
2.8.7
2.8.8
2.8.9
2.8.10
2.8.11
2.8.12
2.8.13
2.8.14
2.8.15
2.8.16
2.8.17
2.8.18
2.8.19
2.8.20
2.8.21
2.8.22
2.8.23
3
3.0
3.0.0
3.0.1
3.0.2
3.0.3
3.0.4
3.0.5
3.0.6
3.0.7
3.0.504
3.2
3.2.0
3.2.1
3.2.2
3.2.3
3.2.4
3.2.5
3.2.6
3.2.7
3.2.8
3.2.9
3.2.10
3.2.11
3.2.100
4
4.0
4.0.0
4.0.1
4.0.2
4.0.4
4.0.5
4.0.6
4.0.7
4.0.8
32bit
alpine
latest
nanoserver
windowsservercore

如果你想要bash_profile版本:

function docker-tags () {
  name=$1
  # Initial URL
  url=https://registry.hub.docker.com/v2/repositories/library/$name/tags/?page_size=100
  (
    # Keep looping until the variable URL is empty
    while [ ! -z $url ]; do
      # Every iteration of the loop prints out a single dot to show progress as it got through all the pages (this is inline dot)
      >&2 echo -n "."
      # Curl the URL and pipe the output to Python. Python will parse the JSON and print the very first line as the next URL (it will leave it blank if there are no more pages)
      # then continue to loop over the results extracting only the name; all will be stored in a variable called content
      content=$(curl -s $url | python -c 'import sys, json; data = json.load(sys.stdin); print(data.get("next", "") or ""); print("n".join([x["name"] for x in data["results"]]))')
      # Let's get the first line of content which contains the next URL for the loop to continue
      url=$(echo "$content" | head -n 1)
      # Print the content without the first line (yes +2 is counter intuitive)
      echo "$content" | tail -n +2
    done;
    # Finally break the line of dots
    >&2 echo
  ) | cut -d '-' -f 1 | sort --version-sort | uniq;
}

并简单地命名为:docker-tags redis

样本输出:

$ docker-tags redis
...
2
2.6
2.6.17
2.8
--trunc----
32bit
alpine
latest
nanoserver
windowsservercore

据我所知,CLI不允许在存储库中搜索/列出标签。

但是如果你知道你想要哪个标签,你可以通过添加冒号和图像名称来显式地拉出它:docker pull ubuntu:saucy

此脚本(Docker -show-repo-tags.sh)应该适用于任何启用Docker的主机,该主机有curl, sed, grep和sort。这已更新,以反映存储库标记url更改的事实。

这个版本在没有JSON解析器的情况下可以正确解析"name":字段。

#!/bin/sh
# 2022-07-20
# Simple script that will display Docker repository tags
# using basic tools: curl, awk, sed, grep, and sort.
# Usage:
#   $ docker-show-repo-tags.sh ubuntu centos
#   $ docker-show-repo-tags.sh centos | cat -n
for Repo in "$@" ; do
    URL="https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/"
    curl -sS "$URL" | 
        /usr/bin/sed -Ee 's/("name":)"([^"]*)"/n12n/g' | 
        grep '"name":' | 
        awk -F: '{printf("'$Repo':%sn",$2)}'
done

这个旧版本不再工作。非常感谢@d9k指出这一点!

#!/bin/sh
# WARNING: This no long works!
# Simple script that will display Docker repository tags
# using basic tools: curl, sed, grep, and sort.
#
# Usage:
#   $ docker-show-repo-tags.sh ubuntu centos
for Repo in $* ; do
    curl -sS "https://hub.docker.com/r/library/$Repo/tags/" | 
        sed -e $'s/"tags":/\n"tags":/g' -e $'s/]/\n]/g' | 
        grep '^"tags"' | 
        grep '"library"' | 
        sed -e $'s/,/,\n/g' -e 's/,//g' -e 's/"//g' | 
        grep -v 'library:' | 
        sort -fu | 
        sed -e "s/^/${Repo}:/"
done

这个旧版本不再工作。非常感谢@viky指出这一点!

#!/bin/sh
# WARNING: This no long works!
# Simple script that will display Docker repository tags.
#
# Usage:
#   $ docker-show-repo-tags.sh ubuntu centos
for Repo in $* ; do
  curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/" | 
    sed -e $'s/,/,\n/g' -e $'s/[/\[n/g' | 
    grep '"name"' | 
    awk -F" '{print $4;}' | 
    sort -fu | 
    sed -e "s/^/${Repo}:/"
done

这是一个简单示例的输出:

$ docker-show-repo-tags.sh centos | cat -n
     1    centos:5
     2    centos:5.11
     3    centos:6
     4    centos:6.10
     5    centos:6.6
     6    centos:6.7
     7    centos:6.8
     8    centos:6.9
     9    centos:7.0.1406
    10    centos:7.1.1503
    11    centos:7.2.1511
    12    centos:7.3.1611
    13    centos:7.4.1708
    14    centos:7.5.1804
    15    centos:centos5
    16    centos:centos5.11
    17    centos:centos6
    18    centos:centos6.10
    19    centos:centos6.6
    20    centos:centos6.7
    21    centos:centos6.8
    22    centos:centos6.9
    23    centos:centos7
    24    centos:centos7.0.1406
    25    centos:centos7.1.1503
    26    centos:centos7.2.1511
    27    centos:centos7.3.1611
    28    centos:centos7.4.1708
    29    centos:centos7.5.1804
    30    centos:latest

我写了一个命令行工具来简化搜索Docker Hub存储库标签,可以在我的PyTools GitHub存储库中找到。它很容易与各种命令行开关一起使用,但最基本的是:

./dockerhub_show_tags.py repo1 repo2

它甚至可以作为Docker镜像使用,并且可以使用多个存储库:

docker run harisekhon/pytools dockerhub_show_tags.py centos ubuntu
DockerHub
repo: centos
tags: 5.11
      6.6
      6.7
      7.0.1406
      7.1.1503
      centos5.11
      centos6.6
      centos6.7
      centos7.0.1406
      centos7.1.1503
repo: ubuntu
tags: latest
      14.04
      15.10
      16.04
      trusty
      trusty-20160503.1
      wily
      wily-20160503
      xenial
      xenial-20160503

如果你想把它嵌入到脚本中,使用-q/--quiet来获取标签,就像普通的Docker命令:

./dockerhub_show_tags.py centos -q
5.11
6.6
6.7
7.0.1406
7.1.1503
centos5.11
centos6.6
centos6.7
centos7.0.1406
centos7.1.1503

v2 API似乎使用了某种分页,因此它没有返回所有可用的标记。这在python(或library/python)等项目中是清晰可见的。即使在快速阅读了文档之后,我也无法正确地使用API(可能是错误的文档)。

然后我使用v1 API重写了脚本,它仍然使用jq:

#!/bin/bash
repo="$1"
if [[ "${repo}" != */* ]]; then
    repo="library/${repo}"
fi
url="https://registry.hub.docker.com/v1/repositories/${repo}/tags"
curl -s -S "${url}" | jq '.[]["name"]' | sed 's/^"(.*)"$/1/' | sort

完整的脚本可在:https://github.com/denilsonsa/small_scripts/blob/master/docker_remote_tags.sh

我还编写了一个改进版本(在Python中),它聚合指向同一版本的标记:https://github.com/denilsonsa/small_scripts/blob/master/docker_remote_tags.py

将此函数添加到.zshrc文件中或手动运行命令:

#usage list-dh-tags <repo>
#example: list-dh-tags node
function list-dh-tags(){
    wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' 'n'  | awk -F: '{print $3}'
}

多亏了这个-> 我如何在远程注册表上列出Docker映像的所有标签?

对于在现代遇到这种情况的人,可以使用Skopeo从Docker注册表中检索图像的标签:

$ skopeo list-tags docker://jenkins/jenkins 
| jq -r '.Tags[] | select(. | contains("lts-alpine"))' 
| sort --version-sort --reverse
lts-alpine
2.277.3-lts-alpine
2.277.2-lts-alpine
2.277.1-lts-alpine
2.263.4-lts-alpine
2.263.3-lts-alpine
2.263.2-lts-alpine
2.263.1-lts-alpine
2.249.3-lts-alpine
2.249.2-lts-alpine
2.249.1-lts-alpine
2.235.5-lts-alpine
2.235.4-lts-alpine
2.235.3-lts-alpine
2.235.2-lts-alpine
2.235.1-lts-alpine
2.222.4-lts-alpine

在sed/AWK上使用Python重新实现上一篇文章:

for Repo in $* ; do
    tags=$(curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/")
    python - <<EOF
import json
tags = [t['name'] for t in json.loads('''$tags''')['results']]
tags.sort()
for tag in tags:
    print "{}:{}".format('$Repo', tag)
EOF
done

对于在Docker Hub上使用OAuth承载令牌的脚本,请尝试如下:

通过HTTP API在Docker hub上列出Docker图像的标签

您可以使用Visual Studio Code为可用的Docker图像和标记提供自动补全。但是,这需要您输入标记的第一个字母才能看到自动完成建议。

例如,当写FROM ubuntu时,它会提供像ubuntuubuntu-debootstrapubuntu-upstart这样的自动补全建议。当编写FROM ubuntu:a时,它提供自动完成建议,如ubuntu:artfulubuntu:artful-20170511.1

最新更新