理解与清理 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 环境的效率,特别是在频繁构建和更新的场景下。

拓展:

相关推荐
dyj0954 小时前
Dify - (一)、本地部署Dify+聊天助手/Agent
人工智能·docker·容器
wanhengidc4 小时前
云手机 高振畅玩不踩坑
运维·服务器·安全·web安全·智能手机
有谁看见我的剑了?4 小时前
linux 添加硬盘后系统识别不到硬盘处理
linux·运维·服务器
JoyCong19985 小时前
ToDesk远程屏幕墙技术白皮书:如何重塑全局运维视界
运维·电脑·远程工作
偶尔上线经常挺尸5 小时前
《100个“反常识”经验15:Nginx 502排查:从应用到内核》
运维·nginx·性能调优·反向代理·502错误·http排错
思茂信息6 小时前
CST软件如何进行参数化扫描?
运维·开发语言·javascript·windows·ecmascript·软件工程·软件需求
计算机安禾6 小时前
【Linux从入门到精通】第31篇:防火墙漫谈——iptables与firewalld防护指南
linux·运维·php
下一页盛夏花开6 小时前
ubuntu 20中安装QT以后出现红色空心断点
linux·运维·ubuntu
Nice_Fold7 小时前
Kubernetes DaemonSet、StatefulSet与Service(自用笔记)
笔记·容器·kubernetes