Comment supprimer des images d'un registre docker privé?

je dirige un registre docker privé, et je veux supprimer toutes les images sauf le latest d'un dépôt. Je ne veux pas supprimer tout le dépôt, juste quelques-unes des images qu'il contient. Le API docs ne mentionne pas une façon de le faire, mais est-ce possible?

97
demandé sur Hosam Aly 2014-08-22 02:09:29

8 réponses

Actuellement, vous ne pouvez pas utiliser l'API Registre pour cette tâche. Il ne vous permet de supprimer qu'un dépôt ou une balise spécifique.

en général, supprimer un dépôt signifie que toutes les étiquettes associées à ce rapport sont supprimées.

supprimer une balise signifie que l'association entre une image et une balise est supprimée.

aucun des éléments ci-dessus ne supprimera une seule image. Ils sont laissés sur votre disque.


solution de Contournement

pour cette solution, vous devez avoir vos images docker stockées localement.

une solution de rechange pour votre solution serait de supprimer toutes les balises sauf les plus récentes et donc potentiellement supprimer la référence aux images associées. Ensuite, vous pouvez lancer ce script pour supprimer toutes les images, qui ne sont référencées par aucune étiquette ou l'ascendance de toute image utilisée.

terminologie (images et étiquettes)

considérez un graphique d'image comme ceci où les lettres majuscules ( A , B , ...) représentent des IDs d'image courts et <- signifie qu'une image est basée sur une autre image:

 A <- B <- C <- D

maintenant nous ajoutons des tags à l'image:

 A <- B <- C <- D
           |    |
           |    <version2>
           <version1>

ici, l'étiquette <version1> renvoie à l'image C et l'étiquette <version2> renvoie à l'image D .

affiner votre question

Dans votre question, vous avez dit que vous vouliez supprimer

toutes les images sauf le latest

. 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 seriez d'accord que l'étiquette <version2> représente la dernière version. En fait, selon cette question vous pouvez avoir une étiquette qui représente la dernière version:

 A <- B <- C <- D
           |    |
           |    <version2>
           |    <latest>
           <version1>

depuis le <latest> image de référence de l'étiquette D je vous demande: Voulez - vous vraiment supprimer tout sauf l'image D ? Probablement pas!

que se passe-t-il si vous supprimez une étiquette?

si vous supprimez la balise <version1> en utilisant L'API Docker REST vous obtiendrez ceci:

 A <- B <- C <- D
                |
                <version2>
                <latest>

souvenez-vous: Docker ne supprimera jamais une image! Même s'il l'a fait, dans ce cas il ne peut pas supprimer une image, puisque l'image C fait partie de l'ascendance pour l'image D qui est marquée.

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

Lorsqu'une image peut être supprimée

sous le condition que vous pouvez contrôler quand quelqu'un peut tirer ou pousser à votre registre (par exemple en désactivant L'interface REST). Vous pouvez supprimer une image d'un graphique d'image si aucune autre image n'est basée sur elle et qu'aucune balise ne s'y réfère.

notez que dans le graphique suivant, l'image D est pas basé sur C mais sur B . Par conséquent, D ne dépend pas de C . Si vous supprimez l'étiquette <version1> dans ce graphe, l'image C ne sera utilisée par aucune image et ce script peut le supprimer.

 A <- B <--------- D
      \            |
       \           <version2>
        \          <latest>
         \ <- C
              |
              <version1>

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

 A <- B <- D
           |
           <version2>
           <latest>

C'est ça que tu veux?

76
répondu Konrad Kleine 2017-05-23 12:26:33

j'ai fait face au même problème avec mon registre puis j'ai essayé la solution indiquée ci-dessous à partir d'une page de blog. Elle fonctionne.

Étape 1: Liste des catalogues de

vous pouvez lister vos catalogues en appelant cette url:

http://YourPrivateRegistyIP:5000/v2/_catalog

la réponse sera dans le format suivant:

{
  "repositories": [
    <name>,
    ...
  ]
}

Étape 2: Liste des balises pour les catalogue

vous pouvez lister les étiquettes de votre catalogue en appelant cette url:

http://YourPrivateRegistyIP:5000/v2/<name>/tags/list

la réponse sera dans le format suivant:

{
"name": <name>,
"tags": [
    <tag>,
    ...
]

}

Étape 3: Liste de la valeur du Manifeste pour l'étiquette connexe

vous pouvez exécuter cette commande dans le conteneur docker registry:

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

la réponse sera dans le format suivant:

sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073

exécuter la commande ci-dessous avec la valeur manifeste:

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

Étape 4: Supprimer les manifestes marqués

exécutez cette commande dans votre conteneur Docker registy:

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

voici ma 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
31
répondu Yavuz Sert 2017-05-04 15:20:14

le registre actuel v2 supporte maintenant la suppression via DELETE /v2/<name>/manifests/<reference>

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

usage courant: https://github.com/byrnedo/docker-reg-tool

Edit: Le manifeste <reference> ci-dessus peut être récupéré à partir de la demande à

GET /v2/<name>/manifests/<tag>

et vérification de l'en-tête Docker-Content-Digest dans la réponse.

31
répondu byrnedo 2018-08-09 11:22:00

Problème 1

vous avez mentionné qu'il s'agissait de votre registre docker privé, de sorte que vous devez probablement cocher API de Registre au lieu de Hub registry API doc , qui est le lien que vous avez fourni.

problème 2

L'API de registre docker est un protocole client / serveur, c'est à l'implémentation du serveur de décider de supprimer ou non les images dans le back-end. (Je suppose)

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

explication détaillée

ci-dessous je Démo comment cela fonctionne maintenant à partir de votre description que ma compréhension pour vos questions.

vous exécutez vous exécutez Docker privé registre, j'utilise celui par défaut et écouter dans 5000 port

docker run -d -p 5000:5000 registry

puis je marque l'image locale et je pousse dedans.

$ 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 API de Registre pour vérifier qu'il existe dans votre registre docker privé

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

maintenant je peux supprimer la balise en utilisant cette API !!

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

Vérifiez encore, 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"}
13
répondu Larry Cai 2017-05-16 12:05:37

C'est vraiment laid mais ça marche, le texte est testé sur le registre:2.5.1. Je n'ai pas réussi à faire en sorte que delete fonctionne correctement même après avoir mis à jour la configuration pour activer delete. L'ID était vraiment difficile à récupérer, il a fallu se connecter pour l'obtenir, peut-être un malentendu. Quoi qu'il en soit, les travaux suivants:

  1. Se connecter au conteneur

    docker exec -it registry sh
    
  2. définir les variables correspondant à votre conteneur et version conteneur:

    export NAME="google/cadvisor"
    export VERSION="v0.24.1"
    
  3. passer à l'annuaire du registre:

    cd /var/lib/registry/docker/registry/v2
    
  4. supprimer les fichiers relatifs à votre hachage:

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

    rm -rf ./repositories/$NAME/_manifests/tags/$VERSION
    
  6. Déconnexion

    exit
    
  7. Exécuter la 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és.

10
répondu hirro 2016-10-28 07:17:04

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


Donc deckschrubber c'est ma solution:

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

les images plus anciennes qu'un âge donné sont automatiquement supprimées. L'âge peut être spécifié en utilisant -year , -month , -day , ou combinaison des deux:

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

mise à JOUR : voici une courte introduction sur deckschrubber.

6
répondu Yan Foto 2017-05-19 09:45:54

cette image de docker inclut un script bash qui peut être utilisé pour supprimer des images d'un registre v2 distant : https://hub.docker.com/r/vidarl/remove_image_from_registry/

0
répondu Vidar Langseid 2017-09-14 10:38:54

ci-dessous Bas Bash Script supprime toutes les étiquettes 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.distribution.manifest.v2+json'  | grep Docker-Content-Digest | awk '{print }' )
            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.distribution.manifest.v2+json' 
        done
    fi
fi
done

après cette course

docker exec $(docker ps | grep registry | awk '{print }') /bin/registry garbage-collect /etc/docker/registry/config.yml
0
répondu Shree Tiwari 2018-07-26 17:38:55