当前位置: 首页 > news >正文

【Docker基础】Docker镜像管理:docker rmi、prune详解

目录

引言

1 Docker镜像管理概述

1.1 为什么需要镜像清理?

1.2 镜像生命周期管理

2 docker rmi命令详解

2.1 基本语法

2.2 常用选项

2.3 删除单个镜像

2.4 删除多个镜像

2.5 强制删除镜像

2.6 删除所有镜像

3 docker rmi工作原理

3.1 镜像删除流程

3.2 镜像分层删除机制

4 docker prune命令详解

4.1 docker image prune

4.2 删除悬空镜像

4.3 删除所有未被使用的镜像

4.4 使用过滤条件

4.5 系统级清理

5 docker prune工作原理

5.1 资源清理流程

5.2 资源识别机制

6 实践应用场景

6.1 日常维护脚本

6.2 开发环境空间回收

7 安全操作示例

7.1 删除镜像前的检查

7.2 重要镜像保护

7.3 定期清理策略

7.4 空间监控

8 常见问题与解决方案

8.1 删除镜像时报错"image is referenced in multiple repositories"

8.2 删除镜像后磁盘空间未释放

8.3 误删了重要镜像

8.4 prune命令删除了需要保留的资源

9 总结


引言

在Docker的日常使用中,镜像管理是至关重要的环节,随着开发和部署的进行,系统中会积累大量镜像,这些镜像占用磁盘空间并可能造成管理混乱。本文将探讨两个关键的镜像管理命令:docker rmi和docker prune。

1 Docker镜像管理概述

1.1 为什么需要镜像清理?

Docker镜像采用分层存储结构,这种设计虽然提高了存储效率,但也带来了以下问题:
  • 磁盘空间占用:镜像会随时间积累,占用大量磁盘空间
  • 版本混乱:同一镜像的多个版本可能同时存在
  • 安全隐患:过时的镜像可能包含已知漏洞

1.2 镜像生命周期管理

理解镜像的生命周期有助于我们更好地管理Docker环境,从上图可以看出,docker rmi和docker prune处于生命周期的末端,负责清理不再需要的镜像

2 docker rmi命令详解

docker rmi(Remove Image)命令用于删除一个或多个Docker镜像。

2.1 基本语法

docker rmi [OPTIONS] IMAGE [IMAGE...]

2.2 常用选项

选项

说明

-f, --force

强制删除镜像,即使有容器正在使用它

--no-prune

不删除未被标记的父镜像

2.3 删除单个镜像

docker rmi ubuntu:20.04

2.4 删除多个镜像

docker rmi ubuntu:20.04 nginx:latest

2.5 强制删除镜像

  • 当镜像被容器使用时,需要添加-f参数:
docker rmi -f ubuntu:20.04

2.6 删除所有镜像

  • 结合docker images -q可以删除所有镜像:
docker rmi $(docker images -q) 
#危险操作警告:这会删除所有本地镜像,请谨慎使用!

3 docker rmi工作原理

3.1 镜像删除流程

  • 用户通过Docker客户端发出docker rmi命令
  • Docker客户端将请求发送给Docker守护进程
  • 守护进程检查镜像是否被容器使用
  • 如果没有容器使用,则解除镜像引用并删除未引用的层
  • 如果有容器使用且没有-f参数,则返回错误
  • 最终将操作结果返回给用户

3.2 镜像分层删除机制

Docker镜像由多个只读层组成,删除镜像时:
  • 首先移除该镜像的标签引用
  • 然后检查各层是否还被其他镜像引用
  • 只有不被任何镜像引用的层才会被实际删除
如果删除镜像A:
  • 层1会被删除(仅被A引用)
  • 层2会被保留(还被镜像B引用)
  • 镜像A的标签被移除

4 docker prune命令详解

docker prune是一组用于清理Docker资源的命令,我们主要关注镜像相关的清理。

4.1 docker image prune

  • 删除未被使用的镜像(悬空镜像):
docker image prune [OPTIONS]
  • 常用选项:

选项

说明

-a, --all

删除所有未被容器使用的镜像(不只是悬空镜像)

--filter

提供过滤条件

-f, --force

不提示确认

4.2 删除悬空镜像

docker image prune

4.3 删除所有未被使用的镜像

docker image prune -a

4.4 使用过滤条件

docker image prune --filter "until=24h"

4.5 系统级清理

  • docker system prune可以一次性清理多种Docker资源:
docker system prune [OPTIONS]
  • 常用选项:

选项

说明

-a, --all

删除所有未使用的镜像(不只是悬空镜像)

--volumes

同时删除未使用的卷

-f, --force

不提示确认

5 docker prune工作原理

5.1 资源清理流程

  • 根据命令参数确定清理范围(镜像、容器、网络、卷等)
  • 扫描系统中所有相关资源
  • 识别符合删除条件的资源(未被使用、悬空等)
  • 如果没有-f参数,则提示用户确认
  • 执行实际删除操作
  • 释放磁盘空间
  • 操作完成

5.2 资源识别机制

  • docker prune识别未使用资源的标准:

资源类型

判断标准

悬空镜像

没有标签且不被任何镜像引用的镜像层

未使用镜像

没有被任何容器(包括停止的)使用的镜像

停止的容器

状态为Exited的容器

未使用的网络

没有被任何容器使用的自定义网络

未使用的卷

没有被任何容器引用的卷

6 实践应用场景

6.1 日常维护脚本

  • 可以创建定期执行的清理脚本:
#!/bin/bash# 删除所有停止的容器
docker container prune -f# 删除所有未被使用的网络
docker network prune -f# 删除所有悬空镜像
docker image prune -f# 删除超过一周前的未使用镜像
docker image prune -a --force --filter "until=168h"

6.2 开发环境空间回收

  • 当开发环境磁盘空间不足时:
# 全面清理所有未使用资源(包括未使用的卷) 
docker system prune -af --volumes

7 安全操作示例

7.1 删除镜像前的检查

在删除镜像前,建议先检查:
  • 哪些容器在使用该镜像:
docker ps -a --filter ancestor=IMAGE_NAME
  • 镜像的详细信息:
docker ps -a --filter ancestor=IMAGE_NAME

7.2 重要镜像保护

对于重要镜像,可以:
  • 推送到镜像仓库备份
  • 使用docker save导出为文件:
docker save -o backup.tar IMAGE_NAME

7.3 定期清理策略

建议建立定期清理策略:
  • 每天清理悬空镜像
  • 每周清理未使用的镜像
  • 每月全面清理整个系统

7.4 空间监控

  • 设置磁盘空间监控,当Docker占用超过阈值时触发清理:
# 检查Docker磁盘使用情况 
docker system df

8 常见问题与解决方案

8.1 删除镜像时报错"image is referenced in multiple repositories"

问题原因:同一个镜像ID有多个标签引用
解决方案
  • 先删除所有引用该镜像的标签:
docker rmi repo1:tag repo2:tag
  • 或者使用镜像ID删除:
docker rmi IMAGE_ID

8.2 删除镜像后磁盘空间未释放

问题原因:Docker使用存储驱动可能缓存了数据
解决方案
  • 重启Docker服务:
systemctl restart docker
  • 清理构建缓存:
docker builder prune

8.3 误删了重要镜像

恢复方案
  • 如果镜像来自仓库,重新拉取
  • 如果有容器基于该镜像运行,可以提交容器为新镜像:
docker commit CONTAINER_ID new_image_name

8.4 prune命令删除了需要保留的资源

预防措施
  • 执行前先使用--dry-run查看将删除的内容:
docker system prune --dry-run
  • 使用--filter精确控制删除范围

9 总结

通过合理使用docker rmi和docker prune命令,可以有效管理Docker镜像,保持系统清洁和高效运行。记住定期清理未使用的资源,但也要谨慎操作,避免误删重要镜像。
http://www.lryc.cn/news/573403.html

相关文章:

  • 竞业限制协议能单独充当商业秘密的 “保护伞” 吗?
  • docker执行yum报错Could not resolve host: mirrorlist.centos.org
  • python web开发-Flask 蓝图(Blueprints)完全指南
  • 【Docker 08】Compose - 容器编排
  • C#测试调用EPPlus根据批注设置excel单元格内容
  • JavaEE初阶第三期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(一)
  • 【开源项目】当大模型推理遇上“性能刺客”:LMCache 实测手记
  • linux安装minio并使用
  • 在Docker、KVM、K8S常见主要命令以及在Centos7.9中部署的关键步骤学习备存
  • XCUITest + Objective-C 详细示例
  • FastGPT:开启大模型应用新时代(4/6)
  • Springboot 配置 FastJson 替换 Jackson
  • Rabbitmq集成springboot,手动确认消息basicAck、basicNack、basicReject的使用
  • 在 MyBatis 的xml中,什么时候大于号和小于号可以不用转义
  • Axios 在 Vue3 项目中的使用:从安装到组件中的使用
  • 升级到 .NET 9 分步指南
  • “最浅”的陷阱:聊聊二叉树最小深度的递归坑点与解法哲学
  • 秋招Day14 - MySQL - SQL优化
  • c++11标准(5)——并发库(互斥锁)
  • 一、什么是生成式人工智能
  • 终端里的AI黑魔法:OpenCode深度体验与架构揭秘
  • Java ArrayList集合和HashSet集合详解
  • 【论文笔记】【强化微调】TinyLLaVA-Video-R1:小参数模型也能视频推理
  • 人人都是音乐家?腾讯开源音乐生成大模型SongGeneration
  • 旧物回收小程序开发:开启绿色生活新方式
  • Python列表常用操作方法
  • 从语义到推荐:大语言模型(LLM)如何驱动智能选车系统?
  • 首页实现多级缓存
  • AWS-SAA 第二部份:安全性和权限管理
  • 《map和set的使用介绍》