[TOC]
镜像尺寸变大的原因
- 对编译或运行无关的指令被引入到镜像
- 无用文件,比如编译过程中的依赖文件
- 系统镜像冗余文件多
- 各种日志文件,缓存文件占用磁盘
从精简的镜像开始构建
使用精简版 Linux发行版 镜像开始构建
- alpine https://hub.docker.com/_/alpine
- scratch https://hub.docker.com/_/scratch
优化镜像内部文件
使用 dive 工具来优化镜像文件
快速使用见 docker image 瘦身工具 dive
指令优化
一个常见的案例是打包元数据和缓存
在安装完编译和运行相关的依赖包之后,这些下载的文件就没有存在的必要了
类似clean 的指令可以在很多仓库(如Docker Hub)的Dockerfile 中发现,它们用于清理这类文件
比如
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak
COPY ./sources.list /etc/apt/
# RUN apt-get update
# RUN apt-get install -y curl
RUN apt-get autoclean
RUN apt-get clean
# RUN apt-get autoremove
RUN rm -rf /var/lib/apt/lists/*
Docker 镜像的尺寸是每一个独立镜像层的尺寸之和,这也就是联合文件系统的工作机制。因此,
clean 步骤并没有真正删掉相应的硬盘空间
查询构建过程即可知道
docker build -t demo .
docker history demo
Dockerfile 中每一个指令要么保持镜像尺寸不变,要么增加它的尺寸
同时,每一步还会引入新的元数据信息,使得整体尺寸在增大
为了降低整个镜像的尺寸,清除操作应该在同一镜像层中执行。于是,解决方案是将先前的多条指令合并成一条
使用Bourne shell 提供的&&操作符来实现链接
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak
COPY ./sources.list /etc/apt/
RUN apt-get autoclean \
&& apt-get clean \
&& autoremove \
&& rm -rf /var/lib/apt/lists/*
分离编译镜像和部署镜像
导致镜像过大的无用文件是编译过程中的依赖文件
例如在编译应用程序过程中所依赖的源代码库,如编译文件和头文件
一旦应用程序编译完毕,这些文件就不再有用,因为运行该应用仅需要相关的依赖库
- 使用
docker cp -L
命令 复制运行容器中的可执行文件到Docker 宿主机 - 然后使用
ADD
指令添加必要二进制文件
这种分离优化技术的最佳实践案例是在一个可持续开发流程中的应用程序的场景,并且它由于镜像太大导致传输时间太长
参考
「Allen 谈 Docker 系列」之深刻理解 Docker 镜像大小
如何让Docker基础镜像变得更小
CentOS Dockerfile减少构建镜像大小的方法
网友评论