Harbor鏡像刪除回收?只看這篇

最近,公司的技術平台,運維的破事兒頗多。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部分:

  1. 鏡像元數據(manifests),存儲在docker/registry/v2/repositories目錄中,在這裡會看到registry上的項目、項目中的鏡像、鏡像到Layer的索引資訊。
  2. 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領域所有相關技術棧,也包含職場的苦與樂,希望各位老哥搜索或者掃描下方圖片一鍵關注,給個支援!