
Docker 已成为应用打包和部署的标准工具。随着应用复杂度的增加Docker 镜像往往会变得臃肿不堪,这不仅影响构建和部署效率,还会增加存储成本和安全隐患。本文将深入探讨 Docker 镜像的分析方法,特别是如何使用 Dive 工具进行层级的精细分析,以及一系列经过验证的镜像优化策略,帮助开发者构建更高效、更安全的容器镜像。
Docker 镜像采用分层存储结构,每一层都代表 Dockerfile 中的一个指令执行结果。这种分层机制带来了构建缓存和共享层的优势,但也容易导致镜像膨胀问题。Docker 镜像由多个只读层(Layer)组成,每个层都包含文件系统的变更集。当容器启动时,Docker 会在所有层之上添加一个可写层。这种设计使得多个镜像可以共享相同的底层,从而节省存储空间。
每个层都包含以下关键信息:
Dive(Docker Image Visualization and Exploration)是一款开源的 Docker 镜像分析工具,专门用于可视化探索镜像内容并识别优化机会。它提供了交互式界面,让用户能够逐层分析镜像构成,发现潜在的空间浪费问题。
Dive 提供了四大核心功能,帮助开发者深入了解镜像结构:

1、分层查看 Docker 镜像内容
Dive 的界面分为左右两部分:左侧显示镜像的层级结构,右侧展示选中层及其之前所有层的文件系统内容。用户可以使用方向键在层级间导航,Enter 键进入详细视图,q 键退出。
2、追踪每层的变化
Dive 直观地显示文件在各层级的变化情况,包括文件的修改、添加和删除。用户可以查看特定层的变化或所有累积变化,便于了解镜像是如何演化的。
3、估算镜像效率
在 Dive 的左下角区域,用户可以看到基本的层信息及一个实验性的“镜像效率”指标,该指标推测镜像中浪费的空间(可能源于跨层文件的重复、移动或未完全移除的文件)。Dive 会提供一个百分比得分以及总的浪费文件空间估算。
4、快速的构建和分析周期
使用简单的命令可以将 Docker 镜像的构建和分析结合在一起,例如将 docker build 命令替换为 dive build 命令即可进行即时分析:
#Bash
dive build -t my-node-app .二进制安装:
下载地址:https://github.com/wagoodman/dive/releases
镜像安装:
docker pull wagoodman/dive:latest
使用
二进制安装的解压后直接使用命令:
./dive <your_image>
镜像安装使用
docker run –rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest <your_image>
如下通过dive镜像cf2f0c72f085分析63cb313df7f4这个镜像为例:
1、现有镜像列表

2、通过运行docker run –rm -it -v /var/run/docker.sock:/var/run/docker.sock cf2f0c72f085 63cb313df7f4命令分析63cb313df7f4
3、获取分析数据:


通过Dive分析镜像的数据后按照实际对镜像的构建进行优化。

多阶段构建是Docker镜像优化的“杀手锏”,它允许在一个Dockerfile中使用多个FROM指令,每个阶段可以基于不同的基础镜像,最终只将必要的文件复制到最终镜像中。
优化前(单阶段构建):
#dockerfile
FROM python:3.10
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]优化后(多阶段构建):
#dockerfile
# 构建阶段
FROM python:3.10 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 运行阶段
FROM python:3.10-slim
WORKDIR /appCOPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]多阶段构建特别适合需要编译或复杂构建过程的应用,如 Go、Java 或 Node.js 项目。通过分离构建环境和运行环境,可以显著减少最终镜像的大小。
基础镜像的选择直接影响最终镜像的大小和安全性。以下是常见的基础镜像类型及其特点:
1)标准镜像(如 ubuntu 、 python ) 功能完整但体积较大,包含完整的操作系统工具链。
2)Slim 镜像(如 python:slim ) 移除了非必要的文档和工具,体积约为标准镜像的 60-70%。
3)Alpine 镜像(如 python:alpine ) 基于 Alpine Linux,使用 musl libc 和 busybox,体积非常小(通常 <50MB)。
4)Distroless 镜像(如 gcr.io/distroless/python3 ) 由 Google 维护,仅包含应用及其运行时依赖,没有 shell、包管理器等,安全性最高。
镜像大小对比示例:
选择基础镜像时需权衡功能需求和体积/安全性要求。对于生产环境,推荐使用 Alpine 或 Distroless 等合适的镜像。
Dockerfile 中的每个指令(如 RUN 、COPY 、ADD )都会创建一个新的层。减少层数不仅可以缩小镜像体积,还能加快构建速度。
优化前(多层):
#dockerfile
FROM ubuntu:latest
RUN apt update -y
RUN apt install unzip -y
RUN apt install curl -y
RUN apt install python3 -y优化后(单层):
#dockerfile
FROM ubuntu:latest
RUN apt update -y && \
apt install unzip -y && \
apt install curl -y && \
apt install python3 -y合并指令时需要注意:
在构建过程中会产生许多临时文件和缓存,这些文件在运行时并不需要,但却会增加镜像大小。常见的清理操作包括:
清理 APT 缓存:
#dockerfile
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*清理 NPM 缓存:
#dockerfile
RUN npm install && npm cache clean --force清理 YUM 缓存:
#dockerfile
RUN yum install -y some-package && yum clean all清理 PIP 缓存:
#dockerfile
RUN pip install --no-cache-dir -r requirements.txt删除临时文件:
#dockerfile
RUN curl -O http://example.com/bigfile.tar.gz \
&& tar xzf bigfile.tar.gz \
&& rm bigfile.tar.gz.dockerignore 文件类似于 .gitignore,用于指定哪些文件和目录不应被复制到镜像中。合理配置可以显著减少构建上下文大小和最终镜像体积。
典型的 .dockerignore 内容:
.git
.gitignore
node_modules
*.log
*.tmp
.DS_Store
.env
distDocker 使用联合文件系统(UnionFS),层的顺序会影响缓存利用率和构建速度。基本原则是:
1)将变化频率低的层放在前面(如安装依赖)
2)将变化频率高的层放在后面(如复制源代码)
3)将清理操作放在同一层中执行
优化示例:
#dockerfile
# 先复制依赖描述文件并安装依赖(变化频率低)
COPY package.json yarn.lock ./RUN yarn install
# 然后复制源代码(变化频率高)
COPY . .
# 最后执行构建和清理
RUN yarn build && rm -rf node_modulesDocker BuildKit 是新一代构建工具,提供了许多优化特性:
并行构建:
#Bash
DOCKER_BUILDKIT=1 docker build --progress=plain .缓存管理:
#dockerfile
# syntax=docker/dockerfile:1.4
FROM node:16
RUN --mount=type=cache,target=/var/cache/yarn yarn install安全扫描:
#Bash
docker scan my-image镜像优化不仅是减小体积,还包括提高安全性:
1)使用非root用户运行容器:
#dockerfile
RUN groupadd -r myuser && useradd -r -g myuser myuser
USER myuser2)移除不必要的setuid/setgid权限:
#dockerfile
RUN find / -perm /6000 -type f -exec chmod a-s {} \; || true3)移除调试工具和shell(在 Distroless 镜像中自动处理)
将镜像优化集成到CI/CD流程中可以确保每次构建都符合优化标准:
使用Dive进行CI检查:
#Bash
CI=true dive my-image配置 .dive-ci 文件定义检查规则:
#YAML
rules:
lowestEfficiency: 0.95
highestWastedBytes: 20MB
highestUserWastedPercent: 0.20Docker镜像优化需要从基础镜像选择、构建过程控制、层级优化、文件清理等多个方面综合考虑。通过使用Dive等分析工具,开发者可以深入了解镜像结构,发现优化机会;而通过多阶段构建、精简基础镜像、合并指令层等技术,可以显著减小镜像体积,提高构建和部署效率:
掌握这些优化方法,将帮助开发者构建更高效、更安全的容器化应用,适应快速迭代的现代软件开发需求。
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!