news 2026/6/13 2:57:28

镜像太臃肿?这个神器让你的Docker镜像瘦成闪电!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
镜像太臃肿?这个神器让你的Docker镜像瘦成闪电!

前几天在公司部署服务的时候,发现一个nodejs应用的镜像居然有2.5G!我当时就懵了,这不科学啊,一个简单的web应用怎么可能这么大。同事开玩笑说是不是把整个node_modules都打包进去了…结果还真被他说中了一部分。

这种情况在实际工作中真的太常见了,很多时候我们构建的镜像莫名其妙就变得很大,但是又不知道问题出在哪里。直到我发现了dive这个工具,才算是找到了分析镜像的利器。

dive是什么?为什么要用它

dive是一个用Go语言开发的Docker镜像分析工具,它可以让你深入了解镜像的每一层结构,看到每一层添加了什么文件,删除了什么内容,甚至可以计算出镜像的效率指标。

你可能会问,docker history命令不也能看镜像的层信息吗?确实可以,但是dive的优势在于:

  • 交互式的界面,操作起来更直观
  • 可以浏览每一层的文件系统变化
  • 显示每个文件的大小信息
  • 计算镜像的浪费空间和效率评分
  • 支持CI/CD集成,可以设置镜像大小阈值

说白了,docker history只能告诉你"发生了什么",而dive能告诉你"具体发生了什么,影响有多大"。

安装dive的几种方式

直接下载二进制文件

最简单的方式就是从GitHub releases页面下载对应系统的二进制文件:

# Linuxwgethttps://github.com/wagoodman/dive/releases/download/v0.12.0/dive_0.12.0_linux_amd64.tar.gztar-xzfdive_0.12.0_linux_amd64.tar.gzsudomvdive /usr/local/bin/# macOSbrewinstalldive

使用Docker运行dive

这种方式比较适合不想在本地安装的情况:

dockerrun--rm-it\-v/var/run/docker.sock:/var/run/docker.sock\wagoodman/dive:latest<镜像名>

我个人更喜欢直接安装,因为用起来更方便一些。

从源码编译

如果你想体验最新的功能,可以从源码编译:

goinstallgithub.com/wagoodman/dive@latest

不过说实话,直接用release版本就足够了,我用了这么久也没遇到什么bug。

dive的基本使用方法

安装完成后,使用dive分析镜像非常简单:

dive<镜像名>

比如分析一个nginx镜像:

dive nginx:latest

启动后你会看到一个分屏的界面,左边显示镜像的各个层,右边显示当前选中层的文件系统内容。

界面操作说明:

  • 上下箭头键:选择不同的镜像层
  • Tab键:在左右窗格之间切换焦点
  • 空格键:展开/收起文件夹
  • Ctrl+C:退出程序

深入分析一个臃肿的镜像

让我用一个真实的例子来演示。我之前构建了一个Python应用的镜像,Dockerfile是这样的:

FROM python:3.9 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"]

看起来很正常对吧?但是构建出来的镜像有1.2G。用dive分析一下:

dive myapp:latest

通过dive分析,我发现了几个问题:

1. 基础镜像选择不当

python:3.9这个镜像本身就很大,包含了很多我不需要的系统工具和库。dive显示这个基础层就有900多MB。

在dive界面中,可以看到第一层(基础镜像层)的大小占了整个镜像的大部分。通过Tab键切换到右侧窗格,可以浏览基础镜像包含的文件,发现里面有gcc、各种开发工具等等。

2. pip缓存没有清理

RUN pip install这一层显示增加了300多MB,但实际的Python包应该没这么大。进入这一层的文件系统,发现/root/.cache/pip目录占用了很大空间。

3. 不必要的文件被复制

COPY . . 这一层虽然只有几MB,但是包含了.git目录、pycache、测试文件等不需要的内容。

优化后的Dockerfile

基于dive的分析结果,我重新编写了Dockerfile:

FROM python:3.9-slim WORKDIR /app # 只复制requirements文件,利用Docker缓存 COPY requirements.txt . # 安装依赖并清理缓存 RUN pip install --no-cache-dir -r requirements.txt \ && rm -rf /root/.cache/pip # 只复制需要的应用文件 COPY src/ ./src/ COPY app.py . CMD ["python", "app.py"]

还添加了一个.dockerignore文件:

.git .gitignore README.md Dockerfile .dockerignore __pycache__ *.pyc *.pyo *.pyd .Python .pytest_cache .coverage test/ docs/

重新构建后用dive分析,镜像大小降到了180MB!效果非常明显。

dive的高级功能

效率评分

dive会给你的镜像打一个效率分数。在界面底部可以看到类似这样的信息:

Image efficiency score: 95% Potential wasted space: 12MB

这个评分主要基于:

  • 重复文件的数量
  • 每层的大小合理性
  • 文件的实际利用率

CI/CD集成

dive支持在CI/CD流水线中使用,可以设置镜像大小和效率的阈值:

# 设置镜像最大500MB,效率最低80%dive myapp:latest--ci\--lowestEfficiency=80\--highestWastedBytes=500MB

如果镜像不符合要求,dive会返回非0退出码,可以让构建失败。

我在公司的Jenkins流水线中就加了这个检查,避免有人提交过大的镜像。

输出格式

dive支持多种输出格式,方便集成到其他工具中:

# JSON格式输出dive myapp:latest--jsonoutput.json# 只显示汇总信息dive myapp:latest--ci--quiet-ci

一些实用的分析技巧

1. 对比不同版本的镜像

经常需要对比优化前后的镜像差异,可以分别分析两个镜像:

dive myapp:v1.0 dive myapp:v2.0

通过对比两个版本的层结构和大小变化,可以快速定位问题。

2. 查看多阶段构建的效果

对于多阶段构建的Dockerfile,dive特别有用。可以清楚地看到哪些文件被复制到了最终镜像,哪些留在了构建阶段。

FROM node:16 AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html

用dive分析这种镜像时,可以看到builder阶段的文件没有进入最终镜像,这样确保了镜像的精简。

3. 识别安全风险文件

在分析镜像时,注意查看是否包含了敏感文件,比如:

  • SSH密钥
  • 配置文件中的密码
  • 开发工具和调试信息

dive可以帮你浏览整个文件系统,确保不会意外泄露敏感信息。

常见的镜像优化策略

通过长期使用dive分析各种镜像,我总结了一些常见的优化策略:

选择合适的基础镜像

  • 优先使用slim或alpine版本
  • 避免使用latest标签
  • 根据实际需要选择版本

比如:

  • python:3.9-slim 比 python:3.9 小很多
  • node:16-alpine 比 node:16 更精简
  • golang的编译完成后可以用scratch作为运行镜像

合并RUN指令

每个RUN指令都会创建一个新层,合并相关的RUN指令可以减少层数:

# 不好的写法 RUN apt-get update RUN apt-get install -y git RUN apt-get install -y curl RUN apt-get clean # 好的写法 RUN apt-get update && \ apt-get install -y git curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*

使用.dockerignore

这个真的很重要,很多人容易忽略。就像.gitignore一样,.dockerignore可以避免把不需要的文件复制到镜像中。

清理临时文件

在同一个RUN指令中安装软件并清理:

RUN apt-get update && \ apt-get install -y python3-pip && \ pip3 install -r requirements.txt && \ apt-get remove -y python3-pip && \ apt-get autoremove -y && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

实际应用中的一些坑

1. 删除文件不会减小镜像大小

这是很多新手会遇到的问题。如果在一个RUN指令中创建了文件,然后在另一个RUN指令中删除,文件还是会占用空间。

# 错误的做法 RUN wget https://example.com/largefile.tar.gz RUN tar -xzf largefile.tar.gz && rm largefile.tar.gz # 正确的做法 RUN wget https://example.com/largefile.tar.gz && \ tar -xzf largefile.tar.gz && \ rm largefile.tar.gz

dive可以清楚地显示这种情况,你会看到删除操作创建了一个新层,但总大小没有减少。

2. COPY指令的顺序很重要

Docker的缓存机制是基于层的,如果把经常变化的文件放在前面,会导致后续的层都需要重新构建。

# 不好的顺序 COPY . . RUN pip install -r requirements.txt # 好的顺序 COPY requirements.txt . RUN pip install -r requirements.txt COPY . .

3. 多阶段构建的层共享

使用多阶段构建时,注意不同阶段之间不会共享层,每个FROM都会开始新的层计算。

dive的一些局限性

用了这么久dive,也发现了一些局限性:

  1. 对于压缩层的分析不够详细,有时候显示的大小与实际略有差异
  2. 界面操作需要一定的学习成本,特别是对于习惯图形界面的同学
  3. 分析特别大的镜像时,加载速度会比较慢
  4. 不支持直接分析tar格式的镜像文件

不过这些问题相对于它带来的价值来说都是小问题。

其他类似工具的对比

除了dive,还有一些其他的镜像分析工具:

docker-slim

这个工具不仅能分析镜像,还能自动优化:

docker-slim build myapp:latest

但是自动优化有时候会过于激进,可能会删掉必要的文件。

container-diff

Google开源的工具,主要用于对比两个镜像的差异:

container-diffdiffdaemon://image1:tag daemon://image2:tag

功能比较专一,适合做镜像对比分析。

skopeo

主要用于镜像的复制和检查,也有一些分析功能:

skopeo inspect docker://nginx:latest

相比之下,dive在交互性和详细程度方面还是有明显优势的。

写在最后

镜像优化这个事情说起来简单,做起来却需要很多细节的把控。dive这个工具真的帮了我很大忙,让镜像分析变得直观和高效。

记得第一次用dive的时候,那种"终于知道问题出在哪里"的感觉真的很爽。就像医生给病人做CT扫描一样,能清楚地看到镜像的"内脏结构"。

当然,工具只是手段,关键还是要养成好的构建习惯。合理选择基础镜像、善用.dockerignore、及时清理临时文件…这些看似简单的操作,日积月累下来效果是很明显的。

如果你也经常被镜像大小困扰,强烈建议试试dive。相信我,用过之后你就回不去了。

最后,如果这篇文章对你有帮助的话,别忘了点个赞和转发。有任何问题也欢迎留言交流,我看到会及时回复的。

关注@运维躬行录,一起在运维的路上精进技艺,让每一次部署都更加优雅!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 20:54:17

ASMR音频高效管理:智能下载工具全解析与实战应用

ASMR音频高效管理&#xff1a;智能下载工具全解析与实战应用 【免费下载链接】asmr-downloader A tool for download asmr media from asmr.one(Thanks for the asmr.one) 项目地址: https://gitcode.com/gh_mirrors/as/asmr-downloader 在数字时代&#xff0c;ASMR音频…

作者头像 李华
网站建设 2026/6/13 0:40:09

3步解锁《艾尔登法环》无限可能:Mod Engine 2终极指南

3步解锁《艾尔登法环》无限可能&#xff1a;Mod Engine 2终极指南 【免费下载链接】ModEngine2 Runtime injection library for modding Souls games. WIP 项目地址: https://gitcode.com/gh_mirrors/mo/ModEngine2 还在为游戏内容单一而烦恼吗&#xff1f;想要在《艾尔…

作者头像 李华
网站建设 2026/6/10 15:32:00

Android WebDAV存储提供者的技术架构与实现方案

Android WebDAV存储提供者的技术架构与实现方案 【免费下载链接】webdav-provider An Android app that can expose WebDAV storage to other apps through Androids Storage Access Framework (SAF) 项目地址: https://gitcode.com/gh_mirrors/we/webdav-provider Andr…

作者头像 李华
网站建设 2026/6/10 21:46:20

Free Texture Packer:游戏开发者的终极精灵表生成解决方案

Free Texture Packer&#xff1a;游戏开发者的终极精灵表生成解决方案 【免费下载链接】free-tex-packer Free texture packer 项目地址: https://gitcode.com/gh_mirrors/fr/free-tex-packer 在游戏开发和网页设计中&#xff0c;你是否经常遇到图像资源过多导致加载缓慢…

作者头像 李华
网站建设 2026/6/10 16:02:08

LibreCAD开源CAD软件全面解析

LibreCAD开源CAD软件全面解析 【免费下载链接】LibreCAD LibreCAD is a cross-platform 2D CAD program written in C14 using the Qt framework. It can read DXF and DWG files and can write DXF, PDF and SVG files. The user interface is highly customizable, and has d…

作者头像 李华
网站建设 2026/6/10 20:16:47

微pe官网启动菜单选择进入IndexTTS2专用系统

微pe官网启动菜单选择进入IndexTTS2专用系统 在一场产品演示中&#xff0c;客户临时提出&#xff1a;“能不能让AI用‘悲伤’的语气读一段文案&#xff1f;”现场工程师手忙脚乱地打开命令行、激活环境、调试参数——而观众早已失去耐心。这样的场景&#xff0c;在AI语音技术落…

作者头像 李华