Как найти все теги изображений работающего контейнера Docker? - PullRequest
6 голосов
/ 18 июня 2019

У меня есть куча 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

К сожалениюкажется, нужно вечно, чтобы закончить.Я не уверен, что делаю что-то не так, но это лучшее, что я могу придумать.

Есть идеи о том, как заставить это работать должным образом?

Ответы [ 4 ]

4 голосов
/ 18 июня 2019

Я думаю, что это лучший подход без проверки контейнера, так как docker ps уже распечатывает форму тега изображения docker, в которой создан контейнер.

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

Итак, сначала получаем список запущенных контейнеров,затем проверьте каждое используемое изображение, запустив контейнер и с помощью jq получите все теги репо этого изображения.

Вот вывод.

docker images tags and name

Обновлено:

Здесь вы используете skopeo , вы можете использовать API, но приложите усилия, поэтому, если у вас есть skopeo

Вам не нужно устанавливать skopeo, вы можете запустить контейнер и затем или удалить один раз, чтобы получить результат, или вы можете установить поддержку сценариев как

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

enter image description here

0 голосов
/ 18 июня 2019

Поле RepoDigest в проверке изображения будет иметь ссылку sha256, если вы извлекли изображение из реестра:

docker ps --format '{{.Image}}' | xargs \
  docker image inspect --format '{{if .RepoDigests}}{{index .RepoDigests 0}}{{end}}'

Для одного изображения, например node:latest на вашем хосте, оно выглядит следующим образом:

docker image inspect --format '{{index .RepoDigests 0}}' node:latest

Этот дайджест нельзя изменить путем отправки в реестр с тем же именем тега. Когда вы извлекаете обновленный тег из реестра, вы увидите это дайджест-обновление.

0 голосов
/ 18 июня 2019

Изображения и контейнеры Docker идентифицируются по идентификатору, а для работающего контейнера вы можете получить идентификатор его изображения, а затем вытащить изображение, соответствующее данному идентификатору.

Сначала вам нужно использовать docker inspectна всех ваших работающих контейнерах, чтобы получить sha256 Id изображение, на котором основан контейнер.

docker inspect возвращает идентификатор изображения в "Image":

{
  "Id": "6de053a2afa4499471c5e5c2afe0b0d83c9c7e50fc7e687fb63a7ebfd2bff320",
  ...
  },
  "Image": "sha256:26eb6780e26887a6838684a549562c0404fd85c55f71e0af6c79a4da5505d2a7",
  ....
}

Тогда вам просто нужно получить эти изображения по дайджесту (неизменяемый идентификатор)

$ docker pull node@sha256:the-image-digest-here

или

$ docker pull node@sha256:26eb6780e26887a6838684a549562c0404fd85c55f71e0af6c79a4da5505d2a7

Если вам повезет, изображения, соответствующие этим дайджестам, все еще доступны в док-центре.

После этого вы все еще видите latest изображений. Я предложу вам переименовать эти изображения с соответствующим именем и тегом и перетащить их в собственный репозиторий док-станции, чтобы иметь возможность использовать их напрямую..

0 голосов
/ 18 июня 2019

Для этого можно использовать команду docker inspect. Вы можете посмотреть ответ здесь https://stackoverflow.com/a/54075889/8113039

...