問題:很多none的鏡像無法被刪除
解決過程:
1、通過 docker image prune -f 提示可刪除為 0
2、直接進行刪除報錯:
docker rmi 8f5116cbc201Error 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刪除容器,發現與之關聯的none會自動刪除
docker rm REPOSITORY:TAG
最終方案:
先保存鏡像,關聯的none會自動刪除,最后在導入鏡像,此時之前的none也不會在顯示
docker images -a |grep -v none |awk '{print "docker save "$1":"$2 " >"$2".tar && docker rmi "$1":"$2" && docker load -i "$2".tar && docker image ls -a|grep "$2""}' >docker_image.sh./docker_image.sh
補充
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沒有自動垃圾回收處理機制,未來可能會有這方面的改進,但是目前我們只能這樣手動清理(寫個腳本就好)。