找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1776

积分

0

好友

234

主题
发表于 17 小时前 | 查看: 0| 回复: 0

社群中有运维同行在接手环境时,发现服务器上的 Docker 存在大量 <none> 镜像,一时间不知如何处理。

Docker images 命令显示大量无标签镜像

这个问题其实很多使用 Docker 的开发者或运维人员都会遇到。本文将详细讲解这些 none 镜像产生的原因、如何正确安全地清理,以及如何从源头避免再次出现大量无名镜像。

1 none 镜像是怎么产生的?

首先需要明确,这些 <none> 镜像通常并非异常,而是 “被新镜像顶掉了标签(tag)的旧镜像”

最常见的来源有以下四种:

1.1 反复 build 时使用 latest 标签

在构建镜像时,如果习惯性地使用 latest 标签:

docker build -t app-api:latest .

当你第二次执行相同的构建命令时,会生成一个内容不同的新镜像,latest 这个标签会从旧镜像转移到新镜像上。旧镜像的标签因此被移除,在镜像列表中就会显示为 <none>

1.2 docker-compose / CI 流水线每次自动 build

docker-compose.yml 文件或 CI/CD 流水线配置中,如果指定了 build 操作并且镜像标签固定为 latest

build: .
image: app-api:latest

那么,每次执行 docker-compose up --build 或流水线触发构建时:

  • 都会覆盖 latest 标签。
  • 都会制造一个失去标签的旧镜像,即 <none> 镜像。

docker-compose.yml 中 latest 标签示例

开头提到的那位同行,正是遇到了这个问题。其 docker-compose 中设置了 latest 标签,流水线频繁调用就导致了大量 none 镜像堆积。

1.3 构建失败或中断

第三种情况是镜像构建过程失败或被意外中断。此时 Docker 可能已经生成了一些镜像层,但由于未能成功走到打标签(tag)的步骤,这些中间层也会以 <none> 的形式存在。

1.4 手动调整或删除标签

这种情况相对较少,即手动使用 docker tag 命令更改镜像标签,或使用 docker rmi 仅删除某个标签(而非镜像ID本身)。这些操作都会导致镜像实体仍然存在,但名字(标签)丢失,从而变成 <none>

2 删了 <none>,磁盘空间却不降?

那位同行发现,即使使用 docker rmi 删除了一批 none 镜像,服务器的磁盘空间也未见明显下降。这是为什么呢?

原因在于:被删除的镜像层并没有被物理抹除,而是从“镜像层”,转变为了 “Build Cache 层”

为什么会这样?这与现代 Docker 默认使用的构建引擎 BuildKit 有关。

当你使用 docker rmi 删除镜像时,Docker 会识别到这些镜像层来自之前的 docker build 操作。BuildKit 认为它们正好可以作为下次构建的缓存,以提高构建速度,于是就把它们“收编”进了 Build Cache。

我们可以通过 docker system df 命令来验证这一点。

删除前,系统占用情况可能如下:
docker system df 显示删除前的磁盘占用

删除一批 none 镜像后,再次查看:
docker system df 显示删除后 Build Cache 增加

对比两图可以看到,Images 的数量和大小确实减少了,但 Build Cache 的大小却相应增加了。磁盘总占用自然没有变化。

三、如何正确删除

请按照以下顺序操作,此过程不会影响任何正在运行的服务。为了万无一失,建议在执行前对重要环境进行备份或快照。

第一步:删除已停止的容器

首先清理掉所有已停止运行的容器,释放一部分关联资源。

docker container prune

第二步:删除 <none> 镜像

使用 Docker 提供的镜像修剪命令,它会删除所有未被容器引用的悬空(dangling)镜像,这正是 <none> 镜像的官方名称。

docker image prune

(系统会询问是否继续,输入 y 确认)

第三步:删除 Build Cache(关键步骤)

这是真正释放磁盘空间的关键。此命令会清理构建缓存,包括那些从镜像“转职”过来的缓存层。

docker builder prune

需要注意的是,清除缓存后,下一次执行 docker build 时会因为缺少缓存而变慢。但这能有效释放已被删除镜像占用的存储空间。

第四步:验证空间释放情况

最后,通过以下命令确认清理效果。

docker system df
df -h

此时,你应该能看到服务器的磁盘使用率有了明显的下降。

4 避坑操作

4.1 慎用 docker system prune -a

不要一上来就执行这个“强力”命令:

docker system prune -a

它会删除所有未被任何容器使用的镜像,包括那些有明确标签(如 nginx:latest)但当前未运行容器的镜像。这可能导致你之后需要时得重新拉取镜像,造成不必要的麻烦和时间浪费。该命令还可能清理停止的容器等资源,存在一定风险。

4.2 严禁手动删除 Docker 存储目录

切勿因为磁盘占用高,就直接去操作系统层面删除 Docker 的数据目录,例如:

/var/lib/docker/overlay2

这是 Docker 容器和镜像的底层存储位置,直接删除文件会破坏 Docker 内部的数据层关系,极有可能导致所有容器无法运行、数据丢失,造成严重的服务故障。

请牢记上文所述的“清理四部曲”,使用 Docker 提供的正规命令进行管理,不要直接操作底层文件。

更重要的是理解 Docker 磁盘占用的这套逻辑(镜像层与构建缓存的转换关系),以后再处理此类问题就能得心应手了。

希望这篇关于云原生基础设施中镜像管理的指南能对你有所帮助。如果你在实践过程中遇到其他棘手问题,欢迎在技术社区进行交流探讨,例如在云栈社区的相关板块分享你的经验。

装饰性星星动图




上一篇:从分块到重排:RAG系统六大工程难题与解决方案实战
下一篇:淘特导购团队Java项目AI编程实践:从代码补全、Agent到SDD的演进与思考
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-25 20:35 , Processed in 0.254206 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表