Correctly keeping docker VSTS / Azure Devops build agent clean yet cached Correctly keeping docker VSTS / Azure Devops build agent clean yet cached kubernetes kubernetes

Correctly keeping docker VSTS / Azure Devops build agent clean yet cached


Probably you've already found a solution, but it might be useful for the rest of the community to have an answer here.

docker prune has a limited purpose. It was created to address the issue with cleaning up all local Docker images. (As it was mentioned by thaJeztah here)

To remove images in the more precise way it's better to divide this task into two parts:1. select/filter images to delete2. delete the list of selected images

E.g:

docker image rm $(docker image ls --filter reference=docker --quiet)docker image rm $(sudo docker image ls | grep 1.14 | awk '{print $3}')docker image ls --filter reference=docker --quiet | xargs docker image rm

It is possible to combine filters clauses to get exactly what you what:
(I'm using Kubernetes master node as an example environment)

$ docker imagesREPOSITORY                           TAG                 IMAGE ID            CREATED             SIZEk8s.gcr.io/kube-proxy                v1.14.2             5c24210246bb        3 months ago        82.1MBk8s.gcr.io/kube-apiserver            v1.14.2             5eeff402b659        3 months ago        210MBk8s.gcr.io/kube-controller-manager   v1.14.2             8be94bdae139        3 months ago        158MBk8s.gcr.io/kube-scheduler            v1.14.2             ee18f350636d        3 months ago        81.6MB  # beforequay.io/coreos/flannel               v0.11.0-amd64       ff281650a721        6 months ago        52.6MBk8s.gcr.io/coredns                   1.3.1               eb516548c180        7 months ago        40.3MB  # sincek8s.gcr.io/etcd                      3.3.10              2c4adeb21b4f        8 months ago        258MBk8s.gcr.io/pause                     3.1                 da86e6ba6ca1        20 months ago       742kB$ docker images --filter "since=eb516548c180" --filter "before=ee18f350636d" REPOSITORY               TAG                 IMAGE ID            CREATED             SIZEquay.io/coreos/flannel   v0.11.0-amd64       ff281650a721        6 months ago        52.6MB$ docker images --filter "since=eb516548c180" --filter "reference=quay.io/coreos/flannel" REPOSITORY               TAG                 IMAGE ID            CREATED             SIZEquay.io/coreos/flannel   v0.11.0-amd64       ff281650a721        6 months ago        52.6MB$ docker images --filter "since=eb516548c180" --filter "reference=quay*/*/*" REPOSITORY               TAG                 IMAGE ID            CREATED             SIZEquay.io/coreos/flannel   v0.11.0-amd64       ff281650a721        6 months ago        52.6MB$ docker images --filter "since=eb516548c180" --filter "reference=*/*/flan*" REPOSITORY               TAG                 IMAGE ID            CREATED             SIZEquay.io/coreos/flannel   v0.11.0-amd64       ff281650a721        6 months ago        52.6MB

As mentioned in the documentation, images / image ls filter is much better than docker prune filter, which supports until clause only:

The currently supported filters are: dangling (boolean - true or false)   label (label=<key> or label=<key>=<value>)   before (<image-name>[:<tag>], <image id> or <image@digest>) - filter images created before given id or references since (<image-name>[:<tag>], <image id> or <image@digest>) - filter images created since given id or references

If you need more than one filter, then pass multiple flags (e.g., --filter "foo=bar" --filter "bif=baz")

You can use other linux cli commands to filter docker images output:

grep "something"      # to include only specified imagesgrep -v "something"   # to exclude images you want to savesort [-k colN] [-r] [-g]] | head/tail -nX  # to select X oldest or newest images

Combining them and putting the result to CI/CD pipeline allows you to leave only required images in the local cache without collecting a lot of garbage on your build server.

I've copied here a good example of using that approach provided by strajansebastian in the comment:

#example of deleting all builds except last 2 for each kind of image #(the image kind is based on the Repository value.)#If you want to preserve just last build modify to tail -n+2.# delete dead containersdocker container prune -f# keep last 2 builds for each image from the repositoryfor diru in `docker images --format "{{.Repository}}" | sort | uniq`; do    for dimr in `docker images --format "{{.ID}};{{.Repository}}:{{.Tag}};'{{.CreatedAt}}'" --filter reference="$diru" | sed -r "s/\s+/~/g" | tail -n+3`; do         img_tag=`echo $dimr | cut -d";" -f2`;         docker rmi $img_tag;    done;done# clean dangling images if anydocker image prune -f