harbor定時清理鏡像
分享下最近寫harbor倉庫鏡像自動清理腳本思路,很長時間不寫shell腳本,這次的腳本也是匆匆寫的,還有很多可優化點,感興趣的可以參考自己優化下,寫的不完善地方也希望指出。
說下harbor倉庫清理的思路,其實思路也比較簡單,就是找到要清除的鏡像地址,根據自己需要對時間排序清除不需要的就行。那么關鍵點來了,如何有效找出需清除的鏡像和時間tag關聯起來呢這是問題的核心,在寫腳本前也參考了網上他人的腳本,大部分人都是通過python實現的,用shell實現的也無法滿足我的需求,那接下來刨析下我的腳本。
-
環境需求
harbor1.7.4
保留近期5個鏡像
tag是沒構建一次+1操作,但是因為實際也不確定可能存在誤差就沒有從這個方向考慮
-
思路:
- 找出所有滿足5個鏡像以上的鏡像
- 根據找到的鏡像名稱對應時間排序
- 找到關聯時間的tag刪除
harbor提供了眾多的api,我這里只有一個項目,多個項目的可以參考舉一反三
# 查找項目下所有對應的鏡像信息
curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/search?q=項目名稱"
# 獲取指定鏡像信息(鏡像倉庫地址格式化切割,將"/"換成"%2F")
curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/repositories/鏡像倉庫名稱/tags"
#刪除鏡像(tag根據實際情況來寫)
curl -s -k -X DELETE "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/repositories/鏡像倉庫名稱/tags/具體的tag"
-
找出所有滿足5個鏡像以上的鏡像
# 通過api查找到所有對應的鏡像地址,這里有個"tags_count"就是鏡像的tag數,通過tag數判斷>5篩選出對應的鏡像"repository_name",剛開始一直在想通過管道連接的方式一條語句判斷出來,結果確實沒有想到好的方法判斷出來,退而求其次選擇了現在的方法,將獲取到的值保存到文件中,根據自己的需要構造一個新的文件。 #獲取所有tags_count COUNT=$(curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/search?q=項目名稱 " |grep "\"tags_count\""|awk -F "\"" '{print $3$4}' | awk -F "" '{print $3$4}') #獲取所有repository_name REPS=$(curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/search?q=項目名稱 " |grep "\"repository_name\""|awk -F "\"" '{print $4}') # 接下來就是根據需求造文件,我這里想要的格式是 tags_count ,repository_name在同一行一一對應關聯起來。 for i in $COUNT do echo $i >> test_count.txt done for y in $REPS do echo $y >> test_server.txt done #合並倆個文件拼接出新的文件,新的文件count_and_server.txt里面存放的就是我們造好的數據。 paste test_count.txt test_server.txt > count_and_server.txt #刪除不需要的文件 rm -rf test_count.txt rm -rf test_server.txt rm -rf server.txt #循環讀取每一行並判斷,這里根據tab切割第一個值是tags_count,第二個值對應repository_name,判斷大於5將服務讀取到server.txt,這樣server.txt里面就是我們所有需要清除的鏡像 FILENAME=count_and_server.txt cat $FILENAME | while read LINE do new_str=$(echo $LINE | cut -d " " -f1) new_str1=$(echo $LINE | cut -d " " -f2) if [ $new_str -gt 5 ] then echo $new_str1 >> server.txt fi done
-
根據找到的鏡像名稱對應時間排序並刪除
# 通過server.txt里面的鏡像我們就可以找對應的created時間 # 替換server.txt文件中"/"" sed -i 's@\/@%2F@g' server.txt # #通過server.txt文件找到所有可刪除的時間 SERVER_NAME=server.txt cat $SERVER_NAME | while read LINE do # 繼續造文件,造一個時間和tag名稱對應的文件,這里文件是奇數行是created時間。偶數行是tag名稱 name_date=$(curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/repositories/${LINE}/tags" |egrep "\"created|name\""|awk -F "\"" '{print $4}') for date in $name_date do echo $date >> date.txt done echo "++++++++++++++++++++++++++++++++++" #合並兩行,將時間和tag名稱放到一行一一對應 awk '{if(NR%2!=0)ORS=" ";else ORS="\n"}1' date.txt >> new_date.txt # 按時間排序 sort -r new_date.txt > new1_date.txt #刪除不需要的文件 rm -rf new_date.txt rm -rf date.txt #根據時間排序刪除從第6行開始以后 # !!!這部可以驗證所有待刪除的tag,對比harbor倉庫是否一致 NEW_DEL=new1_date.txt del_tag=$(cat new1_date.txt | tail -n +6 | awk -F' ' '{print $1}') # 可以查看到所有滿足刪除需求的 echo $del_tag echo "===========================================" #根據tag執行軟刪除 #curl -s -k -X DELETE "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/repositories/${LINE}/tags/${del_tag}" done
-
基本上整個腳本就結束了,不過這樣的刪除只是在ui中刪除並不是真正意義的刪除,還需要執行harbor命令清空Gc才能真正釋放資源
#硬刪除,根據自己版本 #cd ${HARBOR_PAHT} #docker-compose stop #docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect --dry-run /etc/registry/config.yml
-
完整腳本走一波
#! /bin/bash HARBOR_PAHT="" COUNT=$(curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/search?q=項目名稱 " |grep "\"tags_count\""|awk -F "\"" '{print $3$4}' | awk -F "" '{print $3$4}') REPS=$(curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/search?q=項目名稱 " |grep "\"repository_name\""|awk -F "\"" '{print $4}') for i in $COUNT do echo $i >> test_count.txt done for y in $REPS do echo $y >> test_server.txt done paste test_count.txt test_server.txt > count_and_server.txt rm -rf test_count.txt rm -rf test_server.txt rm -rf server.txt FILENAME=count_and_server.txt cat $FILENAME | while read LINE do new_str=$(echo $LINE | cut -d " " -f1) new_str1=$(echo $LINE | cut -d " " -f2) if [ $new_str -gt 5 ] then echo $new_str1 >> server.txt fi done sed -i 's@\/@%2F@g' server.txt SERVER_NAME=server.txt cat $SERVER_NAME | while read LINE do name_date=$(curl -s -k -X GET "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/repositories/${LINE}/tags" |egrep "\"created|name\""|awk -F "\"" '{print $4}') for date in $name_date do echo $date >> date.txt done awk '{if(NR%2!=0)ORS=" ";else ORS="\n"}1' date.txt >> new_date.txtawk '{if(NR%2!=0)ORS=" ";else ORS="\n"}1' date.txt >> new_date.txt sort -r new_date.txt > new1_date.txt rm -rf new_date.txt rm -rf date.txt NEW_DEL=new1_date.txt del_tag=$(cat new1_date.txt | tail -n +6 | awk -F' ' '{print $1}') curl -s -k -X DELETE "https://${harbor_user}:${harbor_passwd}@${harbor_url}/api/repositories/${LINE}/tags/${del_tag}" done cd ${HARBOR_PAHT} docker-compose stop docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect --dry-run /etc/registry/config.yml #最后啟動harbor ./install
有更好方法的歡迎討論