隨着容器概念的普及,越來越多的系統以容器的形式部署升級,但隨着時間的推移,我們會發現主機中的鏡像文件越來越多,其中有很多舊版本的鏡像,占用了大量的存儲空間,此時就需要定期清理那些沒有價值的鏡像。
本文會根據筆者所負責的節點進行介紹。
一、介紹
節點特點:
- 節點中部署着多個指定版本的應用系統。
- 節點中存在應用系統歷史版本的docker鏡像文件。
清理目標:
- 清理非當前使用版本的鏡像文件。
- 后續更新時不必花大量的時間重新拉取中間鏡像層。
二、 分析現狀
a. 主機鏡像文件現狀
b. 主機容器運行現狀
c. 制作鏡像的Dockerfile
d. 存儲空間大小
分析:從上面的圖中可知,主機中有如下幾種鏡像:
- 使用中的鏡像:32.1.0.84/test/athena:develop_1749
- 歷史版本鏡像:32.1.0.84/test/athena:develop_1747
- 基礎鏡像:java:8
- dangling鏡像:ID為1a9f88c0c230的鏡像。(是由於使用同一個tag多次構建內容不同的鏡像,導致較早的鏡像變為dangling鏡像)
dangling鏡像和歷史版本鏡像是不再需要的鏡像文件,白白占用了一定的存儲空間,需要清理。使用中的鏡像很明顯不應該被清理。為了避免后續更新時花大量的時間重新拉取,所以基礎鏡像不應該被清理。
三、 分別處理各種鏡像
3.1 dangling鏡像
dangling是一種特殊的,不會再被使用到的鏡像,docker有專門清理dangling鏡像的命令。
docker image prune -f
從圖中可以看出部分docker鏡像已經被清理,並且提示釋放了39.45MB的空間。
檢查一下剩余的鏡像,可以看見dangling鏡像已經不存在了,符合預期。
檢查當前的存儲空間大小,可以發現釋放了40MB的空間,也是符合預期的。
3.2 歷史版本鏡像
直接使用docker刪除鏡像的命令即可。
docker rmi [image]
從圖中可以看出歷史版本的鏡像已經被清理。
檢查一下剩余的鏡像,可以看見歷史版本鏡像已經不存在了。
檢查當前的存儲空間大小,可以發現又釋放了40MB的空間,也是符合預期的。
3.3 使用中的鏡像
筆者需要在批量刪除無用鏡像的時候,保留使用中的鏡像。幸運的是,docker的刪除命令無法直接刪除正在被容器使用的鏡像。測試一下讓自己放心。
3.4 基礎鏡像
為了后續更新的效率,筆者需要在批量刪除無用鏡像的時候,保留基礎鏡像。
由於基礎鏡像沒有被容器直接使用,所以刪除命令可以執行。測試如下:
剛開始看見命令被成功執行時,筆者心中是崩潰的,但是仔細看了一下顯示的刪除過程,發現只有“Untagged”而沒有“Deleted”,心中竊喜,猜測是不是只刪除了tag,鏡像層並沒有被刪除。趕緊檢查一下,果然發現和筆者猜想的一樣,由於基礎鏡像中的鏡像層目前正被容器使用着,所以並未被刪除。
為了證實更新應用鏡像時不會消耗大量時間去拉取基礎鏡像,筆者再次構建應用的鏡像進行檢查從而得以驗證。
四、結論
- dangling鏡像通過命令 docker image prune -f 清理。
- 通過命令 docker images | awk 'NR!=1{print $1":"$2}' | xargs docker rmi 可以批量清除無用的鏡像,且不會影響使用中的鏡像和基礎鏡像,滿足筆者的需求。