如何查找正在运行的Docker容器的所有图像标签? [英] How to find all image tags of a running Docker container?
问题描述
我有一堆运行在服务器上的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屋!