最近,公司的技術平臺,運維的破事兒頗多。Jira無法訪問,ES堆記憶體不足,Jenkins頻繁不工作。。等等等,讓我這個剛入門的小兵抓心腦肝,夜不能寐,關鍵時刻方恨經驗薄弱呀!!一波未平,一波又起,這不,Harbor映象庫又無法訪問了。查了下磁碟,發現/data目錄已經佔用了99%,這還怎麼愉快的工作了。搞他就是了!
使用Harbor API刪除映象
網上找了太多的文章都是通過Python或者shell指令碼寫的,因為自身沒弄過python,shell指令碼也不熟,而且大多不符合我的特殊需求。所以我打算直接使用Spring boot ,並利用Quartz做定時任務檢查,呼叫Harbor API,完成映象的刪除。由於harbor映象庫儲存了公司所有專案的映象,有些倉庫下的映象比較少,時間也比較久遠,不少映象都是繼承的關係,不能單一的按照時間和數量做刪除。這裡我的策略是每個映象倉庫至少保留5個Tag;如果多於5個,則只保留最近15天的Tag。
完整程式碼我已貼到Github上,如果大家需要的話可以在文末找到。
Harbor映象佔用過多磁碟
docker映象是分層的,registry在儲存映象的時候,將docker映象分成了2部分:
- 映象後設資料(manifests),儲存在
docker/registry/v2/repositories
目錄中,在這裡會看到registry上的專案、專案中的映象、映象到Layer的索引資訊。 - blobs,儲存在
docker/registry/v2/blobs
目錄中,在這裡按00-ff分目錄儲存了所有映象的layer。
如果有2個映象使用了同一個基礎映象,那麼在registry上儲存的時候,blobs只有一份資料,而映象後設資料中兩個映象各自的索引都有一部分layer指向相同的layer。
舉個例子。
初始狀態,A、B兩個映象,都是基於layer a所做的映象;A引用a,b,B引用a,c。
A -----> a <----- B
\--> b |
c <--/
之後刪掉B映象(通過Harbor的web,或者通過api)
A -----> a B
\--> b
c
此時layer c實際已經沒人用了,但是registry在刪除B映象時,只是會刪除B的後設資料,並不會主動刪除layer c。
layer c就是無人照看的孤兒待回收的垃圾,需要GC。
果然 /data/registry/docker/registry這個目錄佔了600多GB,我們抓到了真凶。
GC回收
使用API,刪掉映象,UI上確實看不見了,但是我們發現磁碟並未釋放,還需要回收GC。
使用docker ps, 我們可以看見harbor相關的9個容器。
進入映象儲存位置,我們使用 docker exec -it 3501 /bin/bash,進到registry這個容器裡
df -h檢視剩餘空間
先dry-run一下,看看待刪除的報告,此步不會真正執行刪除。
registry garbage-collect --dry-run /etc/registry/config.yml
可以清理的blobs還是挺多的。去掉dry-run,實際跑一下
registry garbage-collect /etc/registry/config.yml
GC效果還可以,清理出來500GB左右的空間。
這裡如果執行刪除時提示對/storage/docker/registry/v2/blobs/sha256/5e/5e526656b6e423eb836829b95951913719a48efa2649189f0a039b068eb59e10/data 沒有許可權,在容器外執行
chmod -R 777 /data/registry/docker/registry/v2
給整個目錄授權即可
Harbor API刪除映象程式碼,可以掃描下方二維碼,關注,並私信,獲取Github連結,還望兄弟們幫忙支援公號。
< END >
如果您喜歡這篇文章,還希望幫忙點贊分享,讓更多的朋友能夠參與其中,分享各自的感悟;也歡迎下方留言,和小夥伴一起探討職場人生。 小墨唯一公眾號 《DevOps特種部隊》,分享我在國企數字化轉型中,DevOps領域所有相關技術棧,也包含職場的苦與樂,希望各位老哥搜尋或者掃描下方圖片一鍵關注,給個支援!