bash 如何查找正在运行的 Docker 容器的所有图像标签?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/56646899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find all image tags of a running Docker container?
提问by Forivin
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 容器在服务器上运行,我对所有容器都使用了“最新”标签或根本不使用标签。现在我想冻结图像版本,但我不知道何时提取这些图像,所以我无法分辨“最新”指的是哪个版本。docker ps
只是向我展示容器使用“最新”或不使用标签,如下所示:
# 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
...
All images that I use are public images from the docker hub.
我使用的所有图像都是来自 docker hub 的公共图像。
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.
我想也许我可以使用 docker ps 为所有容器显示的十六进制 ID,但后来我意识到 ID 是容器 ID 而不是图像 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?
是否有可能获取所有正在运行的容器的图像 ID/哈希,然后扫描所有匹配的标签或类似的东西?
Docker version: 18.09.1, build 4c52b90
Docker 版本:18.09.1,构建 4c52b90
Edit:
编辑:
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)
所以已经有一些答案显示了如何获取图像的 ID(摘要),但我需要以某种方式找到这些图像的实际标签。在做了一些研究之后,我发现 docker hub 有一个 API,并且有一种方法可以获取给定图像的所有标签,并且有一种方法可以获取给定图像 + 标签的摘要。在查看了 API 和来自 stackoverflow 的大量示例后,我想出了这个:(它还包括获取本地图像摘要所需的代码,取自以下答案)
function getDigestByImageNameWithTag () {
TARGET_IMAGE_NAME_WITH_TAG="" # 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=""
TARGET_DIGEST=""
# 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 }' | 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?
关于如何使其正常工作的任何想法?
回答by Adiii
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 ps 已经打印了创建容器的 docker 图像标签表单。
docker inspect $(docker ps | awk '{print }' | grep -v ID) | jq .[].RepoTags
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.
因此,首先获取正在运行的容器列表,然后检查正在运行的容器正在使用的每个映像并使用jq
获取该映像的所有 repo 标签。
Here is the output.
这是输出。
Updated:
更新:
Here is you go using skopeo, you can do using API but will do the effort, so why if you have skopeo
这是你去使用skopeo,你可以使用 API 但会努力,所以为什么如果你有 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
你不需要安装skopeo
你可以运行容器然后或删除一次得到结果,或者你可以安装,脚本支持两者
running_container=$(docker ps | awk '{print }' | grep -v ID)
echo "running container: $running_container"
for image in $running_container
do
local_tag=$(echo "$image" | awk -F":" '{print }')
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 }' | 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
回答by BMitch
The RepoDigest field in the image inspect will have a sha256 reference if you pulled the image from a registry:
如果您从注册表中提取图像,图像检查中的 RepoDigest 字段将具有 sha256 引用:
docker ps --format '{{.Image}}' | xargs \
docker image inspect --format '{{if .RepoDigests}}{{index .RepoDigests 0}}{{end}}'
For a single image like node:latest
on your host, that looks like:
对于像node:latest
主机上的单个图像,它看起来像:
docker image inspect --format '{{index .RepoDigests 0}}' node:latest
That digest cannot be changed by a push to the registry of the same tag name. When you pull the updated tag from the registry, you will see this digest update.
该摘要不能通过推送到相同标签名称的注册表来更改。当您从注册表中提取更新的标记时,您将看到此摘要更新。
回答by Danish Faizan
The docker inspect command can be used for this. You can take a look at the answer here https://stackoverflow.com/a/54075889/8113039
docker inspect 命令可用于此目的。你可以看看这里的答案https://stackoverflow.com/a/54075889/8113039
回答by Guillaume Barré
Docker images and containers are identified by an ID and for a running container you can get the Id of its image and then pull the image corresponding to the given ID.
Docker 镜像和容器由 ID 标识,对于正在运行的容器,您可以获取其镜像的 ID,然后拉取与给定 ID 对应的镜像。
First you need to use docker inspect
on all your running containers in order to get the sha256
Id the image on which the container is based.
首先,您需要docker inspect
在所有正在运行的容器上使用,以获取sha256
容器所基于的映像的Id。
docker inspect
returns the image ID under "Image"
:
docker inspect
返回下的图像 ID "Image"
:
{
"Id": "6de053a2afa4499471c5e5c2afe0b0d83c9c7e50fc7e687fb63a7ebfd2bff320",
...
},
"Image": "sha256:26eb6780e26887a6838684a549562c0404fd85c55f71e0af6c79a4da5505d2a7",
....
}
Then you simply have to pull those images by digest (immutable identifier)
然后您只需通过摘要(不可变标识符)提取这些图像
$ docker pull node@sha256:the-image-digest-here
or
或者
$ docker pull node@sha256:26eb6780e26887a6838684a549562c0404fd85c55f71e0af6c79a4da5505d2a7
If you are lucky images corresponding to those digests are still available into the docker hub.
如果幸运的话,与这些摘要相对应的图像仍然可以在 docker hub 中使用。
After that, is you are still facing latest
images I will suggest you to rename those images with a proper name and tag and pull them in your own docker hub repository to be able to use them directly...
在那之后,您是否仍然面对latest
图像,我建议您使用适当的名称和标签重命名这些图像,并将它们拉入您自己的 docker hub 存储库中,以便能够直接使用它们...