理解与清理 Docker 中的悬空镜像(Dangling Images)

目录

  • [理解与清理 Docker 中的悬空镜像(Dangling Images)](#理解与清理 Docker 中的悬空镜像(Dangling Images))
    • [1. 什么是悬空镜像(Dangling Images)?](#1. 什么是悬空镜像(Dangling Images)?)
    • [2. 悬空镜像是如何产生的?](#2. 悬空镜像是如何产生的?)
      • [(1) 构建新镜像时覆盖旧标签](#(1) 构建新镜像时覆盖旧标签)
      • [(2) 删除镜像后遗留的中间层](#(2) 删除镜像后遗留的中间层)
      • [(3) 使用 docker pull 更新镜像](#(3) 使用 docker pull 更新镜像)
    • [3. 如何清理悬空镜像?](#3. 如何清理悬空镜像?)
      • [(1) 基本清理(仅删除悬空镜像)](#(1) 基本清理(仅删除悬空镜像))
      • [(2) 强制清理(无需确认)](#(2) 强制清理(无需确认))
      • [(3) 清理所有未被使用的镜像(不仅仅是悬空镜像)](#(3) 清理所有未被使用的镜像(不仅仅是悬空镜像))
      • [(4) 结合过滤条件清理](#(4) 结合过滤条件清理)
    • [4. 如何避免悬空镜像积累?](#4. 如何避免悬空镜像积累?)
      • [(1) 使用 --force-rm 避免构建残留](#(1) 使用 --force-rm 避免构建残留)
      • [(2) 使用多阶段构建(Docker 17.05+)](#(2) 使用多阶段构建(Docker 17.05+))
      • [(3) 定期执行自动清理](#(3) 定期执行自动清理)
    • [5. 总结](#5. 总结)

理解与清理 Docker 中的悬空镜像(Dangling Images)

1. 什么是悬空镜像(Dangling Images)?

悬空镜像是指 没有标签(Tag)未被任何容器引用 的 Docker 镜像层。它们通常是构建或删除镜像时遗留下来的中间层,不再被使用但仍然占据存储空间。

Example:查看悬空镜像

bash 复制代码
docker images -f "dangling=true"

输出可能类似:

复制代码
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
<none>      <none>    123456789abc   2 hours ago    350MB

可以看到,这些镜像没有 REPOSITORYTAG,仅有一个 IMAGE ID,这就是典型的悬空镜像。


2. 悬空镜像是如何产生的?

(1) 构建新镜像时覆盖旧标签

bash 复制代码
docker build -t my-app:1.0 .
# 再次构建同一个标签
docker build -t my-app:1.0 .

第二次构建后,旧的 my-app:1.0 镜像会变成 <none>:<none>,成为悬空镜像。

(2) 删除镜像后遗留的中间层

bash 复制代码
docker rmi my-app:1.0

如果该镜像有未被引用的依赖层,它们可能会变成悬空镜像。

(3) 使用 docker pull 更新镜像

bash 复制代码
docker pull nginx:latest
# 当新版本推送后,再次拉取
docker pull nginx:latest

旧版本的 nginx:latest 会变成 <none>:<none>,成为悬空镜像。


3. 如何清理悬空镜像?

Docker 提供了 docker image prune 命令专门用于清理悬空镜像。

(1) 基本清理(仅删除悬空镜像)

bash 复制代码
docker image prune

默认会提示确认,输入 y 后删除。

(2) 强制清理(无需确认)

bash 复制代码
docker image prune -f

(3) 清理所有未被使用的镜像(不仅仅是悬空镜像)

bash 复制代码
docker image prune -a

⚠️ 注意:这会删除所有未被容器引用的镜像,包括可能有用的缓存镜像,使用需谨慎!

(4) 结合过滤条件清理

bash 复制代码
# 删除超过 24 小时的悬空镜像
docker image prune --filter "until=24h"

4. 如何避免悬空镜像积累?

(1) 使用 --force-rm 避免构建残留

bash 复制代码
docker build --force-rm -t my-app:1.0 .

这样可以在构建失败时自动清理中间层。

(2) 使用多阶段构建(Docker 17.05+)

bash 复制代码
# 第一阶段:构建环境
FROM golang:1.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# 第二阶段:仅保留可执行文件
FROM alpine:latest
COPY --from=builder /app/myapp /usr/local/bin/myapp # 这里的 /app/myapp 来源于上面的构建
CMD ["myapp"]

这样能减少不必要的镜像层,降低悬空镜像的产生。

(3) 定期执行自动清理

可以在 CI/CD 流程或 cron 任务中加入自动清理:

bash 复制代码
docker image prune -f

或者结合 system prune 清理整个 Docker 系统:

bash 复制代码
docker system prune -f

5. 总结

关键点 说明
悬空镜像是什么? 无标签且未被引用的镜像层
如何查看? docker images -f "dangling=true"
如何清理? docker image prune(基础)、docker image prune -a(彻底)
如何避免? 使用 --force-rm、多阶段构建、定期清理

悬空镜像虽然不会影响运行中的容器,但会占用磁盘空间。定期清理可以提高 Docker 环境的效率,特别是在频繁构建和更新的场景下。

拓展:

相关推荐
XIAOHEZIcode1 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220702 天前
如何搭建本地yum源(上)
运维
武子康2 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
大树885 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠5 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质5 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工5 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn865 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
酣大智5 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_5 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化