У меня есть куча 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
...
Все изображения, которые я использую, являются общедоступными изображениями из концентратора докеров.
Я подумал, что, возможно, смогу использовать шестнадцатеричный идентификатор, который показывает docker ps для всех контейнеров, но потом я понял, что идентификаторы - это идентификаторы контейнеров, а не идентификаторы изображений.
Возможно ли получить идентификаторы / хэши изображений всех запущенных контейнеров, а затем отсканировать все подходящие теги или что-то подобное?
Версия Docker: 18.09.1, сборка 4c52b90
Редактировать:
Итак, было несколько ответов, показывающих, как получить идентификаторы (дайджесты) изображений, но мне нужно каким-то образом найти фактические теги этих изображений.Проведя некоторые исследования, я обнаружил, что у док-концентратора есть API, и что есть способ получить все теги для данного изображения, и есть способ получить дайджест для данного изображения + тега.Посмотрев API и множество примеров из stackoverflow, я пришел к следующему: (Он также включает в себя код, необходимый для получения дайджеста локальных изображений, взятый из ответов ниже)
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
К сожалениюкажется, нужно вечно, чтобы закончить.Я не уверен, что делаю что-то не так, но это лучшее, что я могу придумать.
Есть идеи о том, как заставить это работать должным образом?