背景
偶然間發現服務器上有很多鏡像占用不少空間,想清理一下。
結果直接進行刪除報錯:
docker rmi 8f5116cbc201
Error response from daemon: conflict: unable to delete 8f5116cbc201 (cannot be forced) - image has dependent child images
然后上網需求方法,主流的方法有兩種
方法一:強制刪除鏡像
docker rmi -f 8f5116cbc201
Error response from daemon: conflict: unable to delete 8f5116cbc201 (cannot be forced) - image has dependent child images
以失敗告終。。。
方法二:批量刪除容器,再刪除鏡像 # 停止所有容器 docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop # 刪除所有容器 docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm # 刪除所有none鏡像 docker images|grep none|awk '{print $3 }'|xargs docker rmi
還是以失敗告終。。。。。
原因
搜了很久,發現其實是因為TAG的問題,即有其他 image FROM 了這個 image,可以使用下面的命令列出所有在指定 image 之后創建的 image 的父 image
方案
先查詢依賴
docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=XXX) # XXX指鏡像ID
然后根據根據TAG刪除容器
docker rm REPOSITORY:TAG
補充
docker none鏡像
有效的 none 鏡像
Docker文件系統的組成,docker鏡像是由很多 layers組成的,每個 layer之間有父子關系,所有的docker文件系統層默認都存儲在/var/lib/docker/graph目錄下,docker稱之為圖層數據庫。
最后做一個總結< none>:< none> 鏡像是一種中間鏡像,我們可以使用docker images -a來看到,他們不會造成硬盤空間占用的問題(因為這是鏡像的父層,必須存在的),但是會給我們的判斷帶來迷惑。
無效的 none 鏡像
另一種類型的 < none>:< none> 鏡像是dangling images ,這種類型會造成磁盤空間占用問題。
像Java和Golang這種編程語言都有一個內存區,這個內存區不會關聯任何的代碼。這些語言的垃圾回收系統優先回收這塊區域的空間,將他返回給堆內存,所以這塊內存區對於之后的內存分配是有用的
docker的懸掛(dangling)文件系統與上面的原理類似,他是沒有被使用到的並且不會關聯任何鏡像,因此我們需要一種機制去清理這些懸空鏡像。
我們在上文已經提到了有效的< none>鏡像,他們是一種中間層,那無效的< none>鏡像又是怎么出現的?這些 dangling鏡像主要是我們觸發 docker build 和 docker pull命令產生的。
使用下面的命令可以清理
docker rmi $(docker images -f “dangling=true” -q)
docker沒有自動垃圾回收處理機制,未來可能會有這方面的改進,但是目前我們只能這樣手動清理(寫個腳本就好)。