如何查找正在运行的Docker容器的所有图像标签? [英] How to find all image tags of a running Docker container?

查看:79
本文介绍了如何查找正在运行的Docker容器的所有图像标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆运行在服务器上的Docker容器,我对所有容器都使用了最新"标签或根本没有标签.现在,我想冻结图像版本,但是我不知道何时拉出这些图像,因此我无法确定最新"是指哪个版本. docker ps只是向我显示容器使用最新"标签或不使用标签,例如:

I have a bunch of Docker containers running on a server and I used the "latest" tag or no tag at all for all of them. Now I want to freeze the image versions, but I have no idea when I pulled these images, so I can't tell which version "latest" is referring to. docker ps is just showing me that the containers use the "latest" or no tag, like this:

# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS               NAMES
371d6675888b        node:latest            "npm start"              6 days ago          Up 2 hours                              project_xyz_1
ca5a75425a34        selenium/node-chrome   "/usr/bin/nohup go..."   6 days ago          Up 2 hours                              project_xyz-chrome_1
...

我使用的所有图像都是来自docker hub的公共图像.

All images that I use are public images from the docker hub.

我想也许我可以对所有容器使用docker ps显示的十六进制ID,但是后来我意识到这些ID是容器ID,而不是映像ID.

I thought maybe I could use the hex ID that docker ps shows for all the containers, but then I realized that the IDs are container IDs and not image IDs.

是否有可能获取所有正在运行的容器的图像ID/哈希值,然后扫描所有匹配的标签或类似内容?

Is it maybe possible to get the image IDs/hashes of all running containers and then scan for all matching tags or something like that?

Docker版本:18.09.1,内部版本4c52b90

Docker version: 18.09.1, build 4c52b90

因此,有一些答案显示了如何获取图像的ID(摘要),但是我需要以某种方式找到这些图像的实际标签. 经过研究后,我发现docker hub具有API,并且有一种方法可以获取给定图像的所有标签,并且有一种方法可以获取给定image + tag的摘要.在查看了API和来自stackoverflow的许多示例之后,我想到了这一点: (它还包括获取本地图像摘要所需的代码,取自下面的答案)

So there have been some answers showing how to get the IDs (digests) of the images, but I need to somehow find the actual tags of those images. After doing some research, I found that the docker hub has an API and that there is a way to get all tags for a given image and there is a way to get the digest for a given image+tag. After looking at the API and a lot of examples from stackoverflow, I came up with this: (It also includes the code required to get the digest of local images, taken form the answers below)

function getDigestByImageNameWithTag () {
    TARGET_IMAGE_NAME_WITH_TAG="$1" # works with and without tag
    docker image inspect --format '{{index .RepoDigests 0}}' "$TARGET_IMAGE_NAME_WITH_TAG" | cut -d '@' -f2
}

function getTagsByDigest () {
    TARGET_IMAGE_NAME="$1"
    TARGET_DIGEST="$2"

    # prepend the image name with "library/" if it doesn't contain a slash
    if [[ $TARGET_IMAGE_NAME != *"/"* ]]; then
        TARGET_IMAGE_NAME="library/$TARGET_IMAGE_NAME"
    fi

    # get authorization token for the given image name
    TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$TARGET_IMAGE_NAME:pull" | jq -r .token)

    # find all tags for the given image name
    ALL_TAGS=$(curl -s -H "Authorization: Bearer $TOKEN" https://index.docker.io/v2/$TARGET_IMAGE_NAME/tags/list | jq -r .tags[])

    # itate over all these tags
    for TAG in ${ALL_TAGS[@]}; do
        # get image digest
        DIGEST=$(curl -s -D - -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://index.docker.io/v2/$TARGET_IMAGE_NAME/manifests/$TAG | grep Docker-Content-Digest | cut -d ' ' -f 2)
        # if the tag matches the given digest
        if [[ $TARGET_DIGEST = $DIGEST ]]; then
            # "return" the tag
            echo "$TAG"
        fi
    done
}

function getContainerImageNames () {
    docker inspect $(docker ps  | awk '{print $2}' | grep -v ID) | jq .[].RepoTags | grep -v "\[" | grep -v "\]" | grep " " | cut -d '"' -f2 | cut -d '/' -f2-
}


# get all image names of all local containers
IMGS_WITH_TAG=$(getContainerImageNames)
# iterate of those image names
for IMAGE_NAME_WITH_TAG in ${IMGS_WITH_TAG[@]}; do
    # get the digest of the current iteration's IMAGE_NAME_WITH_TAG
    DIGEST=$(getDigestByImageNameWithTag $IMAGE_NAME_WITH_TAG)
    echo "TARGET_DIGEST: $DIGEST" 
    # get the raw image name without the tag
    IMAGE_NAME=$(echo "$IMAGE_NAME_WITH_TAG" | cut -d ':' -f1)
    # find all tags for this image that have the same digest
    MATCHING_TAGS=$(getTagsByDigest $IMAGE_NAME $DIGEST)
    echo "Image: $IMAGE_NAME_WITH_TAG"
    echo "Image digest: $IMAGE_NAME"
    echo "Image tags with same digest: "
    echo "$MATCHING_TAGS"
    echo "-----------------------------"
done

不幸的是,它似乎需要永远的时间才能完成.我不确定自己做错了什么,但这是我能想到的最好的办法.

Unfortunately it seems to take forever to finish. I'm not sure if I'm doing something wrong, but that's the best thing I could come up with.

关于如何使其正常工作的任何想法?

Any ideas on how to make this work properly?

推荐答案

我认为这是一种无需检查容器的更好方法,因为docker ps已经打印了创建容器的docker image标签形式.

I think this is a better approach without inspecting the container, as docker ps already printing the docker image tag form which the container is created.

docker inspect $(docker ps  | awk '{print $2}' | grep -v ID) | jq .[].RepoTags

因此,首先获取正在运行的容器的列表,然后检查正在运行的容器使用的每个图像,并使用jq获取该图像的所有回购标签.

So first this gets the list of running containers, then inspect each image being used by running container and using jq get all repo tags of that image.

这是输出.

已更新:

这是您要使用 skopeo 的方法,可以使用API​​,但是会尽力而为,所以为什么要使用skopeo

Here is you go using skopeo , you can do using API but will do the effort, so why if you have skopeo

您不需要安装skopeo,您可以先运行容器,然后再删除,或者一旦获得结果就将其删除,或者您可以安装脚本支持两者

You do not need to install skopeo you can run the container and then or remove once get the result, or you can install, script support both

running_container=$(docker ps  | awk '{print $2}' | grep -v ID) 
echo "running container: $running_container"
for image in $running_container
do
local_tag=$(echo "$image" | awk -F":" '{print $2}')
if [ -z $local_tag ]; then
# if tag is empty then tag is latest
local_tag="latest"
image="$image":"$local_tag"
fi
local_digest=$(docker inspect $image | jq '.[].RepoDigests[]' | awk -F"@" '{print $2}' | tr -d '"')
echo "Local digest is:" $local_digest
remote_digest=$(docker run --rm --env image=$image alexeiled/skopeo:latest ash -c "skopeo inspect docker://docker.io/$image" | jq '.Digest' | tr -d '"' )
echo $remote_digest 

# option2 install the skopeo on your local system
# remote_digest=$(skopeo inspect docker://docker.io/$image | jq '.Digest' | tr -d '"')
echo "Remote digest is : "$remote_digest

if [ "${local_digest}" == "${remote_digest}" ]; then
echo "local image is up to date with remote"
else
echo "Remote image is updated; please run docker pull $image"
fi
done

这篇关于如何查找正在运行的Docker容器的所有图像标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆