Docker镜像无法删除的解决方法
前言
删除镜像报错
1 | Error response from daemon: reference does not exist |
通常意味着 Docker 的内部元数据出现了不一致。
简单来说,Docker 的镜像列表里记录着某个镜像的存在,但当它试图去底层存储中查找并删除该镜像的具体文件时,却发现文件已经不见了或路径对不上。
这种情况常见于 Docker 升级后、非正常关机、或者手动修改了 /var/lib/docker 目录下的文件后。
清理构建缓存和悬空镜像
有时候,这个错误是由构建缓存中的残留引用引起的。尝试清理这些缓存可能会解决问题。
清理悬空镜像(dangling images):
1 | docker image prune |
清理构建缓存(Docker 20.10+):
1 | docker builder prune |
再次尝试删除:
执行完上述命令后,再次尝试删除报错的镜像。
强制删除
虽然这个错误通常表示元数据丢失,但有时强制删除命令能触发 Docker 重新检查依赖关系。
1 | docker rmi -f <镜像ID或名称> |
如果这条命令依然报同样的错误,说明问题确实出在元数据文件上,请继续往下看。
修复 repositories.json 文件
Docker 在 /var/lib/docker/image/ 下维护了一个 repositories.json 文件来记录镜像引用关系。
如果这个文件损坏或包含无效路径或无法访问路径,就会报这个错。
我这里使用这种方法解决了。猜测是国内无法访问
docker.io导致的。
操作步骤:
备份并编辑 repositories.json
建议先备份:
1 | sudo cp /data/tools/docker/image/overlay2/repositories.json /data/tools/docker/image/overlay2/repositories.json.bak |
注意我这里更改了路径,默认路径是 /var/lib/docker/image/overlay2/repositories.json 。
下载
1 | /data/tools/docker/image/overlay2/repositories.json |
修复方法:
检查文件中是否有指向 docker.io/ 的条目,或者寻找与报错镜像相关的条目。
将文件中所有的 docker.io/ 替换为空字符串 "" 可以解决问题,或者直接删除报错镜像对应的 JSON 块。
最好是把文件下载到本地,使用编辑器中替换字符串,防止替换后有相同名称的。
VSCode中查看JSON有相同的Key的时候会显示警告线,方便发现删除后重复的键。
如果有相同名称的删除不用的镜像对应的 JSON 块。
重启 Docker 服务
1 | sudo systemctl restart docker |
再次尝试删除
此时 Docker 会重新加载元数据,通常就可以正常删除了。
彻底重置
如果上述方法都太复杂或者无效,且你不在乎丢失当前的镜像和容器数据,可以重置 Docker 的数据目录。
警告:
这将删除你所有的镜像、容器和卷!
操作
1 | sudo systemctl stop docker |