Comment supprimer des images d’un registre de docker privé?

Je lance un registre de docker privé et je souhaite supprimer toutes les images sauf la latest d’un référentiel. Je ne veux pas supprimer l’intégralité du référentiel, juste quelques images à l’intérieur. Les documents API ne mentionnent pas comment faire cela, mais c’est sûrement possible?

Actuellement, vous ne pouvez pas utiliser l’API de registre pour cette tâche. Il vous permet uniquement de supprimer un référentiel ou une balise spécifique.

En général, la suppression d’un référentiel signifie que toutes les balises associées à ce référentiel sont supprimées.

La suppression d’une balise signifie que l’association entre une image et une balise est supprimée.

Aucune de ces réponses ne supprimera une seule image. Ils sont laissés sur votre disque.


solution de contournement

Pour cette solution de contournement, vous devez stocker vos images de docker localement.

Une solution de contournement pour votre solution consisterait à supprimer tous les tags sauf les derniers, supprimant ainsi potentiellement la référence aux images associées. Vous pouvez ensuite exécuter ce script pour supprimer toutes les images qui ne sont référencées par aucune balise ou l’ascendance d’une image utilisée.

Terminologie (images et tags)

Considérons un graphe d’image comme celui-ci où les lettres majuscules ( A , B , …) représentent des identifiants d’image courts et <- signifient qu'une image est basée sur une autre image:

  A <- B <- C <- D 

Maintenant, nous ajoutons des balises à l'image:

  A <- B <- C <- D | | |   

Ici, la balise référence l'image C et la balise référence l'image D

Affiner votre question

Dans votre question, vous avez dit que vous vouliez supprimer

toutes les images sauf la latest

. Maintenant, cette terminologie n'est pas tout à fait correcte. Vous avez mélangé des images et des tags. En regardant le graphique, je pense que vous conviendrez que la balise représente la dernière version. En fait, selon cette question, vous pouvez avoir une balise qui représente la dernière version:

  A <- B <- C <- D | | |  |   

Etant donné que la balise référence image D je vous demande: voulez-vous vraiment supprimer tout sauf l'image D ? Probablement pas!

Que se passe-t-il si vous supprimez une balise?

Si vous supprimez la balise à l'aide de l'API REST Docker, vous obtiendrez ceci:

  A <- B <- C <- D |   

Rappelez-vous: Docker ne supprimera jamais une image! Même si c'était le cas, dans ce cas, il ne peut pas supprimer une image, car l'image C fait partie de l'ascendance de l'image D qui est étiquetée.

Même si vous utilisez ce script , aucune image ne sera supprimée.

Quand une image peut être supprimée

Sous la condition que vous puissiez contrôler quand quelqu'un peut tirer ou pousser sur votre registre (par exemple en désactivant l'interface REST). Vous pouvez supprimer une image d'un graphe d'image si aucune autre image n'est basée dessus et qu'aucune étiquette ne s'y réfère.

Notez que dans le graphique suivant, l'image D n'est pas basée sur C mais sur B Par conséquent, D ne dépend pas de C Si vous supprimez la balise dans ce graphique, l'image C ne sera utilisée par aucune image et ce script pourra le supprimer.

  A <- B <--------- D \ | \  \  \ <- C |  

Après le nettoyage, votre graphique d'image ressemble à ceci:

  A <- B <- D |   

c'est ce que tu veux?

J’ai rencontré le même problème avec mon registre alors j’ai essayé la solution listée ci-dessous à partir d’une page de blog. Ça marche.

Étape 1: Liste des catalogues

Vous pouvez lister vos catalogues en appelant cette URL:

 http://YourPrivateRegistyIP:5000/v2/_catalog 

La réponse sera au format suivant:

 { "repositories": [ , ... ] } 

Étape 2: Liste des balises pour le catalogue associé

Vous pouvez répertorier les balises de votre catalogue en appelant cette URL:

 http://YourPrivateRegistyIP:5000/v2//tags/list 

La réponse sera au format suivant:

 { "name": , "tags": [ , ... ] 

}

Étape 3: Lister la valeur du manifeste pour la balise associée

Vous pouvez exécuter cette commande dans le conteneur de registre Docker:

 curl -v --silent -H "Accept: application/vnd.docker.dissortingbution.manifest.v2+json" -X GET http://localhost:5000/v2//manifests/ 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}' 

La réponse sera au format suivant:

 sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073 

Exécutez la commande ci-dessous avec une valeur manifeste:

 curl -v --silent -H "Accept: application/vnd.docker.dissortingbution.manifest.v2+json" -X DELETE http://127.0.0.1:5000/v2//manifests/sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073 

Étape 4: Supprimer les manifestes marqués

Exécutez cette commande dans votre conteneur de registre docker:

 bin/registry garbage-collect /etc/docker/registry/config.yml 

Voici mon config.yml

 root@c695814325f4:/etc# cat /etc/docker/registry/config.yml version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry delete: enabled: true http: addr: :5000 headers: X-Content-Type-Options: [nosniff] health: storagedriver: enabled: true interval: 10s threshold: 3 

Le registre v2 actuel prend désormais en charge la suppression via DELETE /v2//manifests/

Voir: https://github.com/docker/dissortingbution/blob/master/docs/spec/api.md#deleting-an-image

Utilisation pratique: https://github.com/byrnedo/docker-reg-tool

Edit: Le manifeste ci-dessus peut être récupéré en demandant à

GET /v2//manifests/

et vérifier l’en Docker-Content-Digest tête Docker-Content-Digest dans la réponse.

Problème 1

Vous avez mentionné qu’il s’agissait de votre registre de docker privé. Vous devez donc probablement vérifier l’ API de registre au lieu de la documentation API du registre Hub , qui est le lien que vous avez fourni.

Problème 2

L’API de registre docker est un protocole client / serveur, il appartient à l’implémentation du serveur de supprimer ou non les images dans le back-end. (J’imagine)

 DELETE /v1/repositories/(namespace)/(repository)/tags/(tag*) 

Explication détaillée

Ci-dessous je montre comment cela fonctionne maintenant à partir de votre description en tant que ma compréhension de vos questions.

Vous exécutez vous exécutez le registre de docker privé, j’utilise celui par défaut et écoutez dans le port 5000

 docker run -d -p 5000:5000 registry 

Ensuite, je marque l’image locale et y insère.

 $ docker tag ubuntu localhost:5000/ubuntu $ docker push localhost:5000/ubuntu The push refers to a repository [localhost:5000/ubuntu] (len: 1) Sending image list Pushing repository localhost:5000/ubuntu (1 tags) 511136ea3c5a: Image successfully pushed d7ac5e4f1812: Image successfully pushed 2f4b4d6a4a06: Image successfully pushed 83ff768040a0: Image successfully pushed 6c37f792ddac: Image successfully pushed e54ca5efa2e9: Image successfully pushed Pushing tag for rev [e54ca5efa2e9] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest} 

Après cela, vous pouvez utiliser l’ API de Registre pour vérifier qu’il existe dans votre registre de docker privé

 $ curl -X GET localhost:5000/v1/repositories/ubuntu/tags {"latest": "e54ca5efa2e962582a223ca9810f7f1b62ea9b5c3975d14a5da79d3bf6020f37"} 

Maintenant, je peux supprimer le tag en utilisant cette API!

 $ curl -X DELETE localhost:5000/v1/repositories/ubuntu/tags/latest true 

Vérifiez à nouveau, la balise n’existe pas dans votre serveur de registre privé

 $ curl -X GET localhost:5000/v1/repositories/ubuntu/tags/latest {"error": "Tag not found"} 

C’est vraiment moche mais ça marche, le texte est testé sur le registre: 2.5.1. Je n’ai pas réussi à faire en sorte que la suppression fonctionne correctement, même après la mise à jour de la configuration pour permettre la suppression. L’identifiant était vraiment difficile à récupérer, il fallait se connecter pour l’obtenir, peut-être un malentendu. En tout cas, les œuvres suivantes:

  1. Connectez-vous au conteneur

     docker exec -it registry sh 
  2. Définissez les variables correspondant à votre version de conteneur et de conteneur:

     export NAME="google/cadvisor" export VERSION="v0.24.1" 
  3. Déplacer vers le répertoire du registre:

     cd /var/lib/registry/docker/registry/v2 
  4. Supprimez les fichiers liés à votre hachage:

     find . | grep `ls ./repositories/$NAME/_manifests/tags/$VERSION/index/sha256`| xargs rm -rf $1 
  5. Supprimer les manifestes:

     rm -rf ./repositories/$NAME/_manifests/tags/$VERSION 
  6. Connectez – Out

     exit 
  7. Exécutez le GC:

     docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml 
  8. Si tout a été fait correctement, certaines informations sur les blobs supprimés sont affichées.

Il y a des clients (en Python, Ruby, etc.) qui font exactement cela. A mon goût, il n’est pas viable d’installer un runtime (par exemple Python) sur mon serveur de registre, juste pour gérer mon registre!


Donc, deckschrubber est ma solution:

 go get github.com/fraunhoferfokus/deckschrubber $GOPATH/bin/deckschrubber 

les images antérieures à un âge donné sont automatiquement supprimées. L’âge peut être spécifié en -year , -month , jour, ou une combinaison des deux:

 $GOPATH/bin/deckschrubber -month 2 -day 13 -registry http://registry:5000 

MISE À JOUR : voici une courte introduction sur deckschrubber.

Cette image de docker comprend un script bash pouvant être utilisé pour supprimer des images d’un registre v2 distant: https://hub.docker.com/r/vidarl/remove_image_from_registry/

Au-dessous de Bash Script Supprime toutes les balises situées dans le registre sauf la dernière.

 for D in /registry-data/docker/registry/v2/repositories/*; do if [ -d "${D}" ]; then if [ -z "$(ls -A ${D}/_manifests/tags/)" ]; then echo '' else for R in $(ls -t ${D}/_manifests/tags/ | tail -n +2); do digest=$(curl -k -I -s -H -X GET http://xx.xx.xx.xx:5000/v2/$(basename ${D})/manifests/${R} -H 'accept: application/vnd.docker.dissortingbution.manifest.v2+json' | grep Docker-Content-Digest | awk '{print $2}' ) url="http://xx.xx.xx.xx:5000/v2/$(basename ${D})/manifests/$digest" url=${url%$'\r'} curl -X DELETE -k -I -s $url -H 'accept: application/vnd.docker.dissortingbution.manifest.v2+json' done fi fi done 

Après cette course

 docker exec $(docker ps | grep registry | awk '{print $1}') /bin/registry garbage-collect /etc/docker/registry/config.yml