How to delete docker image data or layer in nexus3 - docker-registry

I'm trying out nexus oss 3.0.1-01. I have a docker repository setup and I'm able to push and pull images successfully. But I need a way delete images. For docker, deleting a component won't actually delete the actual image layers from the file system because it maybe referred to by other components. So, what is the proper way to handle it?
I even deleted every single components and then ran a scheduled task to compact blob store. But that didn't seem to do much in terms of free up storage space.
My understanding is that there isn't a feature in nexus3 at the moment. If there is, could you please point me to some documentation on it? Otherwise, how is everyone else managing their storage space for docker repository?

We had a user contribute this recently:
https://gist.github.com/lukewpatterson/bf9d19410094ea8bced1d4bb0523b67f
You can read about usage here: https://issues.sonatype.org/browse/NEXUS-9293
As well, a supported feature for this will be coming soon from Sonatype.

This is something that needs to be provided at the Docker Registry level. Currently it appears to be broken on v3.1
Did you try to go to assets and delete the layers? If that did not remove the files from the blob store, along with compact blob store, then it is a Nexus problem.
Make sure to tack this issues and confirm that this is the desired behavior for 3.2
See issues
https://issues.sonatype.org/browse/NEXUS-9497
https://issues.sonatype.org/browse/NEXUS-9293

In Nexus 3.14 you go to WebUI -> Tasks -> Create -> Docker - Delete unused manifests and images
Then another job Admin - Compact blob store to actually rm the files from the Nexus directory.
Before that you need to delete the Nexus components (using the cleanup policy+job), as original poster did.

Related

How to really delete Docker blobs and images to free up space in a private Docker registry

I am having trouble clearing up disk space in a private docker registry I am running. I am also having trouble understanding all the different digest SHAs returned by Docker API calls.
My private docker registry is setup in .../docker/registry/v2 It contains two folders: blobs (~1.4GB) and repositories (~944KB). I've pushed several repositories and multiple tags there.
At first I only needed to remove repo's/tags from being returned by some API calls for front-end display but now I need to free up disk space and can't figure out how.
1. Remove Repo and tag names (cosmetic)
I list docker repositories with their tags on a user front-end by parsing the results of the Docker API calls GET /_catalog and GET /<repo name>/tags/list for each repo. Sometimes I need to delete things so they don't show up in this list and I've been able to do that with the following approach.
GET /<repo name>/manifests/<tag>
DELETE /<repo name>/manifests/<digest SHA in headers.Docker-Content-Digest of the above response>
I'm not sure this is the right way to do this but I needed to somehow control the front-end display and this has worked for now.
This operation reduces the size of the local repositories folder by a few KB but doesn't affect the blobs folder.
2. Clear up disk space and really delete repo's
Where I'm stuck is how to actually free up the large disk space taken up by the blobs directory. There are many different digest SHAs that are returned by GET /<repo name>/manifests/<tag>: body.config.digest and the various body.layers[i].digest.
I tried executing DELETE /<repo name>/blobs/<some digest> on these different digests. For some it is successful, for others it says blob not found. When successful the repositories directory size is reduced by a few KB but blobs directory size doesn't change.
I only tried this after I already hit DELETE /<repo name>/manifests/<headers.Docker-Content-Digest> because I didn't want to accidentally break something and not be able to remove the repo's/tags from the front-end.
My question is: what is the correct way to clear space due to repo's/tags from a private docker registry. My hope is that the best practice will also delete them from the /_catalog and /<repo name>/tags/list as well.
Any insight on the use/meaning of the different digests discussed above would also be greatly appreciated.

After deleting image from Google Container Registry and uploading another with the same tag, deleted one is still pulled

I don't know if this is intended behavior or bug in GCR.
Basically I tried do it like that:
Create image from local files using Docker on Windows (Linux based image).
Before creating image I delete all local images with the same name/tag.
Image is tagged like repostiory/project/name:v1
When testing locally image have correct versions of executables (docker run imageID).
Before pushing image to GCR I delete all images from GCR with the same tag/name.
When Trying to pull new image from GCR to example kubernetes it pull the first (ever) image uploaded under particular tag.
I want to reuse the same tag to not change config file with every test and I don't really need to store previous versions of images.
It sounds like you're hitting the problem described in kubernetes/kubernetes#42171.
tl;dr, the default pull policy of kubernetes is broken by design such that you cannot reuse tags (other than latest). I believe the guidance from the k8s community is to use "immutable tags", which is a bit of an oxymoron.
You have a few options:
Switch to using the latest tag, since kubernetes has hardcoded this in their default pull policy logic (I believe in an attempt to mitigate the problem you're having).
Never reuse a tag.
Switch to explicitly using the PullAlways ImagePullPolicy. If you do this, you will incur a small overhead, since your node will have to check with the registry that the tag has not changed.
Switch to deploying by image digest with the PullIfNotPresent ImagePullPolicy. A more detailed explanation is in the PR I linked, but this gets you the best of both worlds.

Best practice for dockerfile maintain?

I have a Dockerfile something like follows:
FROM openjdk:8u151
# others here
I have 2 questions about the base image:
1. How to get the tags?
Usually, I get it from dockerhub, let's say openjdk:8u151, I can get it from dockerhub's openjdk repository.
If I could get all tags from any local docker command, then I no need to visit web to get the tags, really a little low efficiency?
2. Will the base image safe?
I mean if my base image always there?
Look at the above openjdk repo, it is an offical repo.
I found there is only 8u151 left for me to choose. But I think there should be a lots of jdk8 release during the process, so should also a lots of jdk8 images there, something like 8u101, 8u163 etc.
So can I guess the maintainer will delete some old images for openjdk?
Then if this happen, how my Dockerfile work? I should always change my base image if my upstream delete there image? Really terrible for me to maintain such kind of thing.
Even if the openjdk really just generate one release of jdk8. My puzzle still cannot be avoided, as dockerhub really afford the delete button for users.
What's the best practice, please suggest, thanks.
How to get the tags?
See "How to list all tags for a Docker image on a remote registry?".
The API is enough
For instance, visit:
https://registry.hub.docker.com/v2/repositories/library/java/tags/?page_size=100&page=2
Will the base image safe?
As long as you save your own built image in a registry (eithe rpublic one, or a self-hosted one), yes: you will be able to at least build new images based on the one you have done.
Or, even if the base image disappears, you still have its layers in your own image, and can re-tag it (provided the build cache is available).
See for instance "Is there a way to tag a previous layer in a docker image or revert a commit?".
See caveats in "can I run an intermediate layer of docker image?".

Nexus Repository Manager 3 OSS - Allow re-deploy of Docker Images that fulfills a specific criteria

The Nexus 3 Docker Repo solution requires that re-deploy is allowed in order for the usage of latest tag to work (as described here Allow redeploy for "latest" docker tag in Nexus OSS)
Since we want our uploaded images to be immutable, but at the same time allow the usage of tagging with latest it puts us into a dilemma.
Current best thinking is to have a white-list of tags that can be re-deployed
(tags like latest, production etc)
This means that we must be able to trap any Docker Image upload request prior to that the storage request is processed. In the pre-check we must then block the re-deploy if the image is already present in the repo and that the given image tag is NOT within the white-list..
We already have a custom bundle, so we were hoping that we could extend the functionality with this new blocking feature.
Is it possible to something like this?

Is it possible to commit only a subset of the changes to a docker image?

I am considering using Docker for a project, but I have one question I have not been able to find an answer to in the docs or anywhere else: is it possible to commit only a subset of the changes I make to an image?
Let's say I start a container, make a bunch of changes to the filesystem, get my thing working well and then want to commit them to a new base image. However, I only want a small subset of the changes that were actually made (maybe some of them were to log files, or other things that are unimportant). Does docker commit allow to specify that I only want changes, say, under some part of the filesystem to be committed?
You would just first remove the unnessecary files. To my knowledge, partial commits are not supported.
If you want to do this, using docker diff is really handy. You can easily see what the file system changes are that way. You can even run that against a running container.

Resources