Sie sind auf Seite 1von 4

Docker Registry Cleanup

1. Python Script to delete old tags

Description
Below python script was created to control the number of tags being created in the remote docker registries by
the development teams. The teams follow a practice of using semantic versioning to name the tags for their
docker images.

It parses through the images in the docker registry and keeps only the top 3 major
versions and their top 3 minor versions (For tags that follow semantic versioning). The
script can be deployed as a job if required.

The python script takes "Docker Registry URL" (e.g. https://xxx.registry.xxx.com:10104/v2 ) as


an external variable

Script

import requests
import semantic_version
import os
from distutils.version import LooseVersion
import logging
import datetime
 
#Environment is the only input parameter. Enter the registry URL which needs to be cleaned
 
environment = os.environ['Environment']
print(environment)
 
def main(environment):
global env
env = environment
images = get_images(env)
time = datetime.datetime.now().strftime("%Y%m%d%H%M")
logging.basicConfig(filename="/var/"+time+"_docker_registry_cleanup.log", level=logging.INFO)
logging.info(env)
logging.info(datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
logging.info("Deleted Tags")
 
#log tag names which will be deleted and delete them
for image in images[:]:
tags_to_delete = clean_docker_registry(get_tags(image))[0]
log_tags = ''
if len(tags_to_delete) > 0:
logging.info("Image: "+str(image))
for tag in tags_to_delete:
print(image,tag)
del_image_version(image, tag)
log_tags = log_tags +" "+str(tag)
logging.info("Tags: "+log_tags)
else:
pass
 
versions = get_tags(image)
for version in versions[:]:
if semantic_version.validate(version) == False:
versions.remove(version)
else:
pass
 
versions.sort(key=LooseVersion, reverse = True)
print(image, versions)
print(image, tags_to_delete)
print(" ")
 
 
#log tag names which don't follow semantic versioning but won't be deleted
logging.info("")
logging.info("Invalid Tags")
for image in images[:]:
tags_invalid = clean_docker_registry(get_tags(image))[1]
log_tags = ''
 
if len(tags_invalid) > 0:
logging.info("Image: "+str(image))
for tag in tags_invalid:
print(image,tag)
log_tags = log_tags +" "+str(tag)
logging.info("Tags: "+log_tags)
else:
pass
 
#Function: Get a list of all images in a docker registry
def get_images(env):
environment = env + '/_catalog?n=1000'
r = requests.get(environment, verify=False)
images = r.json()['repositories']
return images
 
#Function: Get a list of all tags in an image (Parameter: Image)
 
def get_tags(image):
tag_url = env+'/'+image+'/tags/list'
 
#get tags from tag_url
r = requests.get(tag_url, verify=False)
 
#check if the the json has a head called tags
if 'tags' in r.json():
 
#check if the tags header is empty
if r.json()['tags'] is not None:
tags=r.json()['tags']
else:
tags = []
 
else:
tags = []
 
return tags
 
 
#Function: Delete image version
 
def del_image_version(image, tag):
 
manifest_url = env+'/'+image+'/manifests/%s'
headers = requests.get(manifest_url % tag, headers = {'Accept':
'application/vnd.docker.distribution.manifest.v2+json'}, verify=False).headers
if 'Docker-Content-Digest' in headers:
requests.delete(manifest_url % headers['Docker-Content-Digest'], verify=False)
 
 
#Function: Use semantic versioning to calculate which image version to delete (Parameter: tags)
 
def clean_docker_registry(versions):
tags_to_keep = []
tags_invalid = []
tags_to_delete = []
release_tags = []
snapshot_tags = []
counter_major = 0
counter_minor = 0
 
if len(versions) != 0:
 
#create a list of all versions which have invalide semantic versioning and delete them from
"versions" List
for version in versions[:]:
if semantic_version.validate(version) == False:
tags_invalid.append(version)
versions.remove(version)
else:
pass
 
#separate snapshots from release versions
for version in versions[:]:
if "SNAPSHOT" in version:
snapshot_tags.append(version)
else:
release_tags.append(version)
 
#Apply logic to release_tags
if len(release_tags) != 0:
 
#sort the versions. For each major version keep the latest 3 minor versions. Keep the latest
3 major versions
try:
release_tags.sort(key=LooseVersion, reverse = True)
major_tag = release_tags[0].split('.')[0]
 
 
for version in release_tags[:]:
if version.split('.')[0] != major_tag and counter_major < 3:
major_tag = version.split('.')[0]
counter_major += 1
counter_minor = 0
tags_to_keep.append(version)
counter_minor += 1
elif version.split('.')[0]==major_tag and counter_minor < 3:
tags_to_keep.append(version)
counter_minor += 1
else:
tags_to_delete.append(version)
except:
pass
else:
pass
 
counter_major = 0
counter_minor = 0
 
#Apply logic to snapshot_tags
if len(snapshot_tags) != 0:
 
#sort the versions. For each major version keep the latest 3 minor versions. Keep the latest
3 major versions
try:
snapshot_tags.sort(key=LooseVersion, reverse = True)
major_tag = snapshot_tags[0].split('.')[0]
 
 
for version in snapshot_tags[:]:
if version.split('.')[0] != major_tag and counter_major < 3:
major_tag = version.split('.')[0]
counter_major += 1
counter_minor = 0
tags_to_keep.append(version)
counter_minor += 1
elif version.split('.')[0]==major_tag and counter_minor < 3:
tags_to_keep.append(version)
counter_minor += 1
else:
tags_to_delete.append(version)
except:
pass
else:
pass
else:
pass
 
#return a list with the tags you want to delete (tags_to_delete)
return tags_to_delete, tags_invalid
 
main(environment)

2. Running garbage collection to delete orphaned layers

Deleting the tags doesn’t create any extra space. For that you have to delete the orphaned docker layers which
get created when tags are deleted. Learn more about garbage collection here:
https://docs.docker.com/registry/garbage-collection/

Das könnte Ihnen auch gefallen