docker鏡像倉庫中鏡像的清理,一直是個比較麻煩的事情。尤其是在測試環境當中,每天都會有大量的構建。由此會產生大量的歷史鏡像,而這些鏡像,大多數都沒有用。
在harbor中,清理鏡像,也得分為兩步,第一步是從ui中刪除歷史鏡像。這個時候鏡像並不會被真正刪除,好在harbor集成了鏡像刪除的功能。
廢話不多說,直接給操作。
清理UI中的鏡像
清理ui中的鏡像,如果直接通過圖形界面一個個的點擊刪除的話,在有大規模鏡像需要清理的時候,簡直就是災難,而且這種方式,實在太low。
我這里簡單寫了個腳本,以實現如下功能:
- 遍歷所有project
- 獲取project中所有tag數超過30的repositories
- 獲取這些tag數超過30的repositories的所有tag
- 基於時間排序,保留最新的30個tag
- 刪除其他tag
腳本示例:
#! /usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import json
class RequestClient(object):
def __init__(self,login_url, username, password):
self.username = username
self.password = password
self.login_url = login_url
self.session = requests.Session()
self.login()
def login(self):
self.session.post(self.login_url, params={"principal": self.username, "password": self.password})
class ClearHarbor(object):
def __init__(self, harbor_domain, password, schema="https",
username="admin"):
self.schema = schema
self.harbor_domain = harbor_domain
self.harbor_url = self.schema + "://" + self.harbor_domain
self.login_url = self.harbor_url + "/login"
self.api_url = self.harbor_url + "/api"
self.pro_url = self.api_url + "/projects"
self.repos_url = self.api_url + "/repositories"
self.username = username
self.password = password
self.client = RequestClient(self.login_url, self.username, self.password)
def __fetch_pros_obj(self):
# TODO
self.pros_obj = self.client.session.get(self.pro_url).json()
return self.pros_obj
def fetch_pros_id(self):
self.pros_id = []
# TODO
pro_res = self.__fetch_pros_obj()
for i in pro_res:
self.pros_id.append(i['project_id'])
return self.pros_id
def fetch_del_repos_name(self, pro_id):
self.del_repos_name = []
repos_res = self.client.session.get(self.repos_url, params={"project_id": pro_id})
# TODO
for repo in repos_res.json():
if repo["tags_count"] > 30:
self.del_repos_name.append(repo['name'])
return self.del_repos_name
def fetch_del_repos(self, repo_name):
self.del_res = []
tag_url = self.repos_url + "/" + repo_name + "/tags"
# TODO
tags = self.client.session.get(tag_url).json()
tags_sort = sorted(tags, key=lambda a: a["created"])
#print(tags_sort)
del_tags = tags_sort[0:len(tags_sort) -30]
#print(del_tags)
for tag in del_tags:
del_repo_tag_url = tag_url + "/" + tag['name']
print(del_repo_tag_url)
del_res = self.client.session.delete(del_repo_tag_url)
self.del_res.append(del_res)
return self.del_res
if __name__ == "__main__":
harbor_domain = "hub.test.com"
password = "xxxxxxx"
res = ClearHarbor(harbor_domain,password)
# 循環所有的project id
for i in res.fetch_pros_id():
# 獲取所有tag超過30的repos
repos = res.fetch_del_repos_name(i)
if repos:
print(repos)
for repo in repos:
del_repos = res.fetch_del_repos(repo)
print(del_repos)
清理鏡像釋放空間
如開篇所說,通過ui清理鏡像並不會真正將這些鏡像從磁盤刪除。要想真正釋放磁盤空間,還得執行如下操作:
# 可以在參數中使用--dry-run以試運行(生產環境中還是盡量試運行下)
docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect /etc/registry/config.yml