Docker completely deletes the private library image

Time:2022-5-8

First, let’s look at the general practice on the Internet

The private library does not support deleting images by default. You need to modify config YML configuration file, add delete: enabled: true under the storage node, and then restart the private library.

The image deletion API provided by docker is:

Delete IP: port / V2 / < repository > / manifest / < reference >

The repository is a mirrored repository

Reference is the Digest: sha256 value generated after the image is successfully pushed

Get Digest:

Curl -- header "accept: application / vnd. Docker. Distribution. Manifest. V2 + JSON" - I - xget < private library IP >: port number / V2 / < image repository > / manifest / < image tag >

be careful:

–The header “accept: application / vnd. Docker. Distribution. Manifest. V2 + JSON” must be added. If not, the content type is V1 + prettyjws, and the digest obtained is wrong!!

Example:


curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -XGET 192.168.120.107:5000/v2/my-registry/manifests/1.0

To delete a mirror:

Example:


curl -I -X DELETE http://192.168.120.107:5000/v2/my-repository/manifests/sha256:4d523adb3c653bab7dfd0326081860b3cba24dc393f69d6731daa513c435ec0c

After deletion, let’s check the private library


curl 192.168.120.107:5000/ v2/my-repository/tags/list

You will find that the tag you just deleted is missing. However, if the file size of the private library image storage directory in the garage before and after the command is executed, it will not change much

Obviously, the data has not been really deleted. We also need to run the garbage collection command provided by docker.

garbage collection

We need to log in to the server where the private library is located, and then execute the command:

Docker exec - it < container ID or container name of Private Library > SH - C 'registry garbage collect / etc / docker / registry / config yml'

Of course, you can also enter the container of the private library and execute:

Docker exec - it < container ID or container name of Private Library > sh
registry garbage-collect /etc/docker/registry/config.yml

This method is particularly troublesome. You can only delete tags, not the repository. After deletion, many empty folders will be left in the blogs directory. Moreover, if there are multiple tags in a repository and the data of these tags are the same, deleting one tag will delete all tags at the same time

Although there are Python scripts on the Internet to delete private library images, I don’t feel easy to use.

I won’t be satisfied with this, so I wrote an SH script myself. Let’s see the effect first.

The script also has some user-friendly tips, and the SH script is easy to understand and expand. I have also uploaded the script to GitHub. If you are interested, you can download it and try it.

GitHub address:https://github.com/hushuai86/docker-delete

Download run:

#First download the script to curl in / usr / local / bin / https://raw.githubusercontent.com/hushuai86/docker-delete/master/docker-delete-2.0.sh  | sudo tee /usr/local/bin/docker-delete >/dev/null

#Give executable permission Chmod a + X / usr / local / bin / docker delete

#Private library image storage directory path global environment variable (this path is the path to mount the / var / lib / registry directory in the private library container to the local machine with the - V command when running the private library container) # example: / opt / data / registry is the path to mount the private library image storage directory to the local directory when I run the container echo "export dock_registry_dir = / opt / data / registry" > > / etc / profile "

#Run private library container ID global environment variable setting (ID of running private library container) # example: 89b9b3c9054ay is the ID of my private library container echo "export dock_registry_container_id = 89b9b3c9054a" > > / etc / profile

#Make configuration effective source / etc / profile

Then you can use the docker delete command. If you feel uncomfortable with the script, you can edit the script and change it yourself

Principle analysis:

(in the screenshot below, / opt / data / registry is the directory where the private library image storage directory is mounted locally when I run the container.)

There are two folders blobs and repositories under the private library image storage directory

The repositories directory contains several files named after the image repository

That is to say, if you want to know which images the private library has, you can directly look at the subfolders of this folder

And in each mirror repository folder/_ You can see which tags the image has in the manifest / tags directory

However, the real data of the image is not stored in the repositories directory, but stored in the blobs directory in the form of data blocks. An image is divided into multiple data blocks, that is, the association relationship of “marking blob…” output when executing the garbage collection command, and the association relationship between the image and the data block is in the repositories / mirror repository/_ Sha256 value in the manifest / revisions / sha256 / directory.

There is a link file in the directory named after the sha256 value, and the content is the sha256 value

After testing, I found that as long as the link file is deleted, then execute the garbage collection command ‘registry garbage collect / etc / docker / registry / config. In the private container YML ‘, then the blobs associated with the sha256 value will be completely deleted

However, an image may have many tags, so which tag does the blobs data associated with the sha256 value belong to?

When we enter a tag / index / sha256 / directory of the image, we will find a folder named after the sha256 value, which exists under the previous revisions / sha256 /. There is also a link file in this folder, which saves the sha256 value.

Therefore, according to my understanding, when we call the API provided by docker to delete a tag, we will obtain the sha256 value in the image tag / index / sha256 / < sha256 value > / link file, and then see if there are other tags associated with the sha256 value. If there are any, only delete the tag folder. If not, When deleting the tag file, the link file corresponding to sha256 in the revisions / sha256 / directory will also be deleted. In this way, when the garbage collection command is executed in the container, the blobs data associated with the sha256 value will be completely deleted.

Special attention:

After completely deleting the data of an image, you need to restart the private library container. If you don’t restart, when you push the image to the private library, you will always output layer already exists, which seems to be pushed up. However, if you delete the local image and then pull, an error will be reported.

Of course, there is this step in my script

The above is my personal experience. I hope I can give you a reference, and I hope you can support developpaer. If you have any mistakes or don’t consider completely, please don’t hesitate to comment.