详解六种减小Docker镜像大小的方法

详解六种减小Docker镜像大小的方法,第1张

详解六种减小Docker镜像大小的方法

本文详细介绍了缩小Docker图像的六种方法。原文根据示例代码非常详细,对大家的学习培训或者工作都有一定的参考价值。有必要的朋友陪我去了解一下。

2017年开始做Vulhub,一直在纠结一个不方便的问题:写Dockerfile时如何缩小dockerbuild形成的图像大小?这篇文章将为你总结六种你用来缩小图片尺寸的方法。

1。应用AlpineLinux

AlpineLinux是基于BusyBox和MuslLibc的Linux发行版,它的一大优势就是体积小。一张纯基本的AlpineDocker图像,缩小后只有2.67MB。

很多官方Docker图片都有Alpine版本,比如PHP:

从下面的对比可以看出,阿尔卑斯版的镜面尺寸是普通版的1/5左右。

但是在DockerHub中,大部分图片都没有Alpine版本,比如Mysql和PHP-Apache。如果非要按照这种自然环境来开发设计,除了自己写阿尔卑斯版,或者找一些第三方镜像,别无选择。

此外,Alpine的另一个缺点是,它使用MuslLibc作为传统glibc的替代品。编写手机软件时,很可能会遇到一些意想不到的问题,导致大家额外消耗大量时间。

2。仅安装至少依赖项

apt-get、yum、apk等包管理工具。是编译图像时必须使用的特殊工具。纯Docker基本映像一般缺少wget、curl、git、gcc等特殊工具。,您必须手动进行设置才能安装它们。

以apt为例。apt-get可以指定一个选项:-no-install-安装程序时的建议。指定了这个主参数之后,一些非必要的依赖项就不容易安装在一起了。例如,当您安装wget时,如果您增加此选项,要安装的软件包数量将从6个减少到3个:

这在一定程度上缩小了图像的大小,但不良反应是目标软件可能会缺少一些功能。

例如,此时,wget将无法验证服务器证书的真实性,从而导致指令失败:

所以大家在应用apt的时候尽可能的升级-不安装-推荐,出现一些错误之后马上纠正,这是惯例。像wget这样的已知问题可以提前预测和解决:

apt-getinstall--no-install-recommendswgetca-certificates

3。为apt擦屁股

一些特殊的工具只在编译过程中使用。我不指望它们会占用我宝贵的图像体积,所以我可以在图像编译后删除这种正向和中间依赖。

以apt为例。申请后,您必须做以下事情:

  • 删除未使用的依赖项:apt-getpruge-autoremove...
  • 删除本地包目录:rm-rf/var/lib/apt/lists/*
  • 在整个过程中,每个人都会遇到一个非常棘手的问题。什么样的依赖是“不必要”的?

    比如编译PHP的时候,你很可能会用到三个特殊的工具:wget、libxml和gcc。这三个特殊工具必须在编译PHP之前安装。但是,编译完成后,我们可以卸载wget和gcc,但不能卸载libxml。

    是的,libxml是PHP依赖的动态链接库。如果我们卸载它,可能会出现无法找到共享链接库的错误:

    root@8eab53da8d5b:/#php-v php:errorwhileloadingsharedlibraries:libxml2.so.2:cannotopensharedobjectfile:Nosuchfileordirectory

    然后,有一个更方便的方法给优木。我只能找到这些不是“共享链接库”的依赖,自动删除。

    很自然,一个很简单的方法就是,你解析刚刚用xml编译的可执行程序,用ldd指令枚举它所依赖的共享链接库的文件夹名,在源码中搜索与这个文件夹名匹配的包名:

    这个包就是PHP依赖的所有动态链接库,然后大家用apt-mark声明这个包是“手工制作并安装的包”,可以防止aptpurge的全自动卸载。

    然后,您可以自动卸载其他未使用的软件包。详细的shell脚本如下所示:

    find/usr/local-typef-executable-execldd'{}'';'\ |awk'/=>/{print$(NF-1)}'\ |sort-u\ |xargs-rdpkg-query--search\ |cut-d:-f1\ |sort-u\ |xargs-rapt-markmanual\ ;\ apt-getpurge-y--auto-remove-oAPT::AutoRemove::RecommendsImportant=false;

    4。将安装和卸载中间依赖项的实际 *** 作尽可能放在一个进程中

    Dockermirror是一个由“层”层压而成的“面饼”。我们可以应用Docker历史;此指令用于查询任意图像由哪些层组成,以及每个层的大小:

    就Dockerfile而言,这一层的数据信息可能存储在镜像中,即使前一层存储的文档被后一层删除。

    例如,您有以下docker文件:

    FROMalpine:3.12 RUNtruncate-s50M/sample.dat RUNrm-rf/sample.dat

    我们可以试试这个图编译多大,58MB:

    相比之下,所有正常的alpine:3.12只有5.57MB,这表明即使所有人都已经删除了/sample.dat文件,但在最终的映像中并没有发现这些内容,而是保留在映像的历史中。

    所以在删除上面提到的“正中间依赖”时,大家一定要把安装、应用、卸载写在一个过程中,保证室内空房间释放。例如:

    FROMdebian:buster RUNapt-getupdate\ &&apt-getinstallgcc\ &&gcc...\ &&apt-getpurge--autoremovegcc\ &&rm-rf/var/lib/apt/lists/*

    5。多链接编译

    Docker版本之后,新导入了多级建筑的定义,可能会大大简化大家提到的所有实际 *** 作。

    简单来说,多级建筑适合大家把Docker图像的编制分成几个“环节”。比如在手机软件编译的一般情况下,我们可以独立明确的提出编译链接,在手机软件编译完成后,立即将二进制文件复制成新的基础镜像。这样做的更大好处是,第二个映像不包括编译链接中所有应用程序的中间依赖项,这是干净整洁的。

    以最常见的新Java项目为例。在编译Jar包时,每个人都必须应用到JDK、Maven等专用工具上,但在具体 *** 作中,每个人只需要JRE自然环境。比较maven:3-openjdk-8和OpenJDK:8-JRE图像的大小:

    相差一倍多。

    以Vulhub中的Shiro1.2.4naturalenvironment为例,可以在其Dockerfile中看到两个FROM命令:

    FROMmaven:3-jdk-8ASbuilder LABELMAINTAINER="phithon<[email protected]>" COPY./code//usr/src/ WORKDIR/usr/src RUNcd/usr/src;\ mvn-Ucleanpackage-Dmaven.test.skip=true FROMopenjdk:8u102-jre LABELMAINTAINER="phithon<[email protected]>" COPY--from=builder/usr/src/target/shirodemo-1.0-SNAPSHOT.jar/shirodemo-1.0-SNAPSHOT.jar EXPOSE8080 CMD["java","-jar","/shirodemo-1.0-SNAPSHOT.jar"]

    第一个FROM用于进入maven的自然环境:3-jdk-8,用maven编译源代码。第二个FROM进入更小的openjdk:8u102-jre自然环境,应用copy-from=English的语法,将过去链接的编译结果中的jar文件复制到jre自然环境中。

    最终设备上会有两个镜像,一个是builder,一个是大家最后需要的shiro1.2.4的自然环境。后者可以由所有其他客户单独应用,而前者可以立即删除。

    对于用户来说,我们不用担心编译手机软件时如何删除中间的依赖关系,让图像变小。简而言之,第一阶段应用程序的所有依赖项都不容易留给宣布的工作环境。

    然而,多链接编译仍然存在上述依赖于动态链接库的问题。如果我们在复制编译结果的时候只复制可执行程序,那么在新的领域 *** 作的时候还是会出现找不到共享链接库的错误。所以我感觉两段式编译只适用于Java、golang等可以混合开发或者静态数据编译的语言,对于C、Python这类严重依赖的新项目还是不太友好。

    6。应用苗条版本的图像

    细心的同学大概注意到了,Docker官网的Debianimage有一个slim版本,比默认版本小了两倍多:

    slim的中文翻译是“苗条”。说白了,debian:stretch-slim确实瘦了很多,因为它删除了很多在器皿里不好用的文档,比如man文本文档。

    有些顶级镜像会按照debian的slim版本来写,比如python。如果我们开发设计一个python的新项目,可以应用python的基本形象:slim。

    综上所述,六种方式都不容易互相伤害,可以分别适用。但第五,多链接编译可能是未来流行的方法。

    到目前为止,这篇关于减小Docker图像大小的六种方法的文章已经在这里详细介绍过了。有关减少Docker图像大小的大量信息,请搜索您以前的文章或再次访问下面的相关文章。期待你以后的申请!

    欢迎分享,转载请注明来源:内存溢出

    原文地址: https://outofmemory.cn/zz/774338.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-03
    下一篇 2022-05-03

    发表评论

    登录后才能评论

    评论列表(0条)

    保存