web-dev-qa-db-fra.com

Comment trouver toutes les balises d'image d'un conteneur Docker en cours d'exécution?

J'ai un tas de conteneurs Docker en cours d'exécution sur un serveur et j'ai utilisé la "dernière" balise ou aucune balise pour tous. Maintenant, je veux figer les versions d'images, mais je n'ai aucune idée quand j'ai tiré ces images, donc je ne peux pas dire à quelle version "la plus récente" fait référence. docker ps me montre simplement que les conteneurs utilisent le "dernier" ou aucun tag, comme ceci:

# 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
...

Toutes les images que j'utilise sont des images publiques du hub docker.

J'ai pensé que je pourrais peut-être utiliser l'ID hexadécimal que docker ps affiche pour tous les conteneurs, mais j'ai réalisé que les ID sont des ID de conteneur et non des ID d'image.

Est-il possible d'obtenir les ID/hachages d'image de tous les conteneurs en cours d'exécution, puis de rechercher toutes les balises correspondantes ou quelque chose comme ça?

Version Docker: 18.09.1, build 4c52b90

Modifier:

Il y a donc eu des réponses montrant comment obtenir les identifiants (résumés) des images, mais je dois en quelque sorte trouver les balises réelles de ces images. Après avoir fait des recherches, j'ai constaté que le hub docker possède une API et qu'il existe un moyen d'obtenir toutes les balises pour une image donnée et qu'il existe un moyen d'obtenir le résumé pour une image + balise donnée. Après avoir regardé l'API et de nombreux exemples de stackoverflow, j'ai trouvé ceci: (Il comprend également le code requis pour obtenir le résumé des images locales, pris sous forme des réponses ci-dessous)

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

Malheureusement, cela semble prendre une éternité pour finir. Je ne sais pas si je fais quelque chose de mal, mais c'est la meilleure chose que j'ai pu trouver.

Des idées sur la façon de faire fonctionner cela correctement?

8
Forivin

Je pense que c'est une meilleure approche sans inspecter le conteneur, car docker ps imprime déjà le formulaire de balise d'image docker dans lequel le conteneur est créé.

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

Donc, tout d'abord, cela obtient la liste des conteneurs en cours d'exécution, puis inspectez chaque image utilisée en exécutant le conteneur et en utilisant jq récupérez toutes les balises repo de cette image.

Voici la sortie.

docker images tags and name

Mise à jour:

Voici que vous allez utiliser skopeo , vous pouvez le faire en utilisant l'API mais fera l'effort, alors pourquoi si vous avez skopeo

Vous n'avez pas besoin d'installer skopeo vous pouvez exécuter le conteneur puis ou supprimer une fois le résultat obtenu, ou vous pouvez installer, le script prend en charge les deux

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

5
Adiii

Le champ RepoDigest dans l'inspection d'image aura une référence sha256 si vous avez extrait l'image d'un registre:

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

Pour une seule image comme node:latest sur votre hôte, qui ressemble à:

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

Ce résumé ne peut pas être modifié par un push vers le registre du même nom de balise. Lorsque vous retirez la balise mise à jour du registre, vous verrez cette mise à jour de résumé.

1
BMitch

Les images et les conteneurs Docker sont identifiés par un ID et pour un conteneur en cours d'exécution, vous pouvez obtenir l'ID de son image, puis extraire l'image correspondant à l'ID donné.

Vous devez d'abord utiliser docker inspect sur tous vos conteneurs en cours d'exécution afin d'obtenir le sha256 Id l'image sur laquelle le conteneur est basé.

docker inspect renvoie l'ID de l'image sous "Image":

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

Ensuite, il vous suffit de tirer ces images par résumé (identifiant immuable)

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

ou

$ docker pull node@sha256:26eb6780e26887a6838684a549562c0404fd85c55f71e0af6c79a4da5505d2a7

Si vous avez de la chance, des images correspondant à ces résumés sont toujours disponibles dans le hub docker.

Après cela, si vous êtes toujours face à des images latest, je vous suggérerai de renommer ces images avec un nom et une balise appropriés et de les insérer dans votre propre référentiel de docker pour pouvoir les utiliser directement ...

0
Guillaume Barré

La commande docker inspect peut être utilisée pour cela. Vous pouvez jeter un oeil à la réponse ici https://stackoverflow.com/a/54075889/8113039

0
Danish Faizan