docker镜像瘦身技术
如何减小docker
制作镜像的大小,一般有以下几种方法:
-
使用较小的基础镜像
-
减少不必要的中间层
# 查看层数
docker inspect image
-
- 使用批量、聚合方式使用
RUN
命令 、COPY
、LABEL
等命令
- 使用批量、聚合方式使用
-
- 使用分阶段构建,减少不必要的中间层
-
减少不必要的组件安装
-
减少不必要文件,或缩减文件大小
启动容器分析目录或文件的磁盘占用
# 发现size比较大的一级目录
find /path/to/dir -maxdepth 1 -type d | xargs -I{} du -sh {}
# 发现比较大的文件,以'1M'为界
find /path/to/dir -size +1M -type f | xargs ls -lh
# 对于发现的文件进行合适的瘦身技术
strip /path/to/somefile
怪异镜像虚胖问题
本来已没有什么可说的,因为用高智能搜索工具,基本上就可以将瘦身技术列出个七七八八。
但是,网上的指导,并没有解决,我遇到的一个奇怪的docker
镜像过大问题。
甚至可以说,仅是由不成熟的使用方式所致,抑或是docker
版本的BUG。
具体制作过程
我在GCC
低版本镜像基础上,继续制作增量镜像,通过Dockerfile RUN native compiling
的方法编译高版本GCC
,形成已完成本地编译的GCC
高版本镜像。
因为本地编译的GCC
,所包括的资料是比较多的,所以,此中间镜像的size比较大。
通过分析,具体指向GCC
编译目录。
但是, 我的目的仅是为了将已本地编译的GCC
编译器部署到一个轻量级的镜像中,所以,实际上可以使用分阶段构建的方法,在GCC
编译目录执行make install DESTDIR=dir
命令,将其安装到任意目录。
遭遇最终镜像虚胖的分阶段构建制作方法
# /path/to/build-parent-dir 包括'build dir'和'source dir'
FROM nativeCompiledGCC:latest AS buildGCC
FROM baseImage:latest
WORKDIR /temp-dir
COPY --from=buildGCC /path/to/build-parent-dir .
RUN cd build && make install DESTDIR=/ && \
rm -rf /temp-dir
ENTRYPOINT ["/bin/bash"]
发现通过这样的分阶段构建技术,竟然最终镜像的size
比较大,像是在中间镜像的基础上,又进行了增量。
启动此最终镜像 的容器,用命令行工具进行分析目录和文件,奇怪地,并没有发现太大目录和文件存在。
后来,深入分析中间镜像的文件占用,发现GCC
编译目录下的build
目录,size
比较大。
虽然,最终镜像通过分阶段构建的方法,确实删除了最终不需要的build
中间目录,但它是否依然影响着docker
镜像Size
和VirtualSize
大小呢?
在最终镜像中尽量避免增删中间目录、文件
那就,试试另外一种分阶段构建的思路,避免将过大的中间目录或文件拷贝入最终镜像,仅将最终需要的目录、文件一次性拷贝入最终镜像
# /path/to/build-parent-dir 包括'build dir'和'source dir'
FROM nativeCompiledGCC:latest AS buildGCC
WORKDIR=/path/to/build-parent-dir/
RUN cd build && make install DESTDIR=/opt/gcc
FROM baseImage:latest
COPY --from=buildGCC /opt/gcc /
ENTRYPOINT ["/bin/bash"]
此种制作方法是OK
的!
结论
制作镜像时,某些比较大size
的中间过程目录或文件,即使在最终镜像中进行了删除动作,但很有可能依然占用docker
镜像的size
,造成镜像虚胖!
希望后期的docker
版本制作分阶段构建镜像,这个问题就不存在了!
在智能搜索之上增加一种镜像瘦身原则
- 尽量使用分阶段构建,并尽量减少在最终镜像增、删中间目录或文件