最近约郁,公司的技術(shù)平臺,運維的破事兒頗多但两。Jira無法訪問鬓梅,ES堆內(nèi)存不足,Jenkins頻繁不工作谨湘。绽快。等等等,讓我這個剛?cè)腴T的小兵抓心腦肝紧阔,夜不能寐坊罢,關鍵時刻方恨經(jīng)驗薄弱呀!擅耽!一波未平活孩,一波又起,這不乖仇,Harbor鏡像庫又無法訪問了憾儒。查了下磁盤,發(fā)現(xiàn)/data目錄已經(jīng)占用了99%这敬,這還怎么愉快的工作了航夺。搞他就是了蕉朵!
使用Harbor API刪除鏡像
網(wǎng)上找了太多的文章都是通過Python或者shell腳本寫的崔涂,因為自身沒弄過python,shell腳本也不熟始衅,而且大多不符合我的特殊需求冷蚂。所以我打算直接使用Spring boot ,并利用Quartz做定時任務檢查汛闸,調(diào)用Harbor API蝙茶,完成鏡像的刪除。由于harbor鏡像庫保存了公司所有項目的鏡像诸老,有些倉庫下的鏡像比較少隆夯,時間也比較久遠,不少鏡像都是繼承的關系,不能單一的按照時間和數(shù)量做刪除蹄衷。這里我的策略是每個鏡像倉庫至少保留5個Tag忧额;如果多于5個,則只保留最近15天的Tag愧口。
完整代碼我已貼到Github上睦番,如果大家需要的話可以在文末找到。
Harbor鏡像占用過多磁盤
docker鏡像是分層的耍属,registry在存儲鏡像的時候托嚣,將docker鏡像分成了2部分:
- 鏡像元數(shù)據(jù)(manifests),存儲在
docker/registry/v2/repositories
目錄中厚骗,在這里會看到registry上的項目示启、項目中的鏡像、鏡像到Layer的索引信息溯捆。 - blobs丑搔,存儲在
docker/registry/v2/blobs
目錄中,在這里按00-ff分目錄存儲了所有鏡像的layer提揍。
如果有2個鏡像使用了同一個基礎鏡像啤月,那么在registry上存儲的時候,blobs只有一份數(shù)據(jù)劳跃,而鏡像元數(shù)據(jù)中兩個鏡像各自的索引都有一部分layer指向相同的layer谎仲。
舉個例子。
初始狀態(tài)刨仑,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實際已經(jīng)沒人用了飞涂,但是registry在刪除B鏡像時,只是會刪除B的元數(shù)據(jù)祈搜,并不會主動刪除layer c较店。
layer c就是無人照看的孤兒待回收的垃圾,需要GC容燕。
果然 /data/registry/docker/registry這個目錄占了600多GB梁呈,我們抓到了真兇。
GC回收
使用API蘸秘,刪掉鏡像官卡,UI上確實看不見了蝗茁,但是我們發(fā)現(xiàn)磁盤并未釋放,還需要回收GC寻咒。
使用docker ps, 我們可以看見harbor相關的9個容器评甜。
進入鏡像存儲位置,我們使用 docker exec -it 3501 /bin/bash仔涩,進到registry這個容器里
df -h查看剩余空間
先dry-run一下忍坷,看看待刪除的報告,此步不會真正執(zhí)行刪除熔脂。
registry garbage-collect --dry-run /etc/registry/config.yml
可以清理的blobs還是挺多的佩研。去掉dry-run,實際跑一下
<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 12px !important; background: rgb(238, 238, 238); border: 0px; border-radius: 2px;">registry garbage-collect /etc/registry/config.yml</pre>
GC效果還可以霞揉,清理出來500GB左右的空間旬薯。
這里如果執(zhí)行刪除時提示對/storage/docker/registry/v2/blobs/sha256/5e/5e526656b6e423eb836829b95951913719a48efa2649189f0a039b068eb59e10/data 沒有權(quán)限,在容器外執(zhí)行
chmod -R 777 /data/registry/docker/registry/v2
給整個目錄授權(quán)即可