1、背景交代
事情的起因是这样的······
2022年7月25日,测试部的几位同事,突然扔了一张表格到群里,然后说:“现在应用的镜像,和上个版本相比,基本上都大了500M左右”
what? 每个镜像的大小都大了500M?
我不记得,我修改过基础镜像的大小,那如果应用的包,也没有增加,那更有可能是哪里导致的呢?
你猜的没错,就是dockerfile编写的方式。
2、查看dockerfile和镜像层大小
既然有了一点的思路,那咱们就要看看dockerfile是怎么编写的,于是乎,我立刻登上主机,找到了某个服务对应的dockerfile文件,内容是这样的:
FROM tomcat:9.0.53-jdk8u202-alpine ADD uap-base_ypr.xml /var/ypr/ ADD ROOT.war /usr/local/tomcat/webapps/ RUN cd /usr/local/tomcat/webapps/ && mkdir -p ROOT && unzip -o ROOT.war -d ROOT/ && rm -fr ROOT.war WORKDIR /usr/local/tomcat/webapps/
在看看这个ROOT.war包的大小:
[root@bip180 uap-base]# ls -lh ROOT.war -rw-r--r-- 1 root root 764M Jul 21 16:24 ROOT.war [root@bip180 uap-base]#
在看看这个镜像构建的每个层的大小:
够了,够了,真相大白了。
就是dockerfile在ADD的部分,增加了ROOT.war,形成了一个镜像层,然后在RUN的部分解压,又多了一层(虽然在RUN中删除了ROOT.war的源文件,但是,这是另外一层),所以再加上基础的镜像,就自然多出来一个应用ROOT.war的大小了。
上面也就是,镜像大小增加的原因了(看来测试的同学,还不是胡搅蛮缠,瞎说的)
那问题的原因也找到了,我们的目标呢,也是要减少镜像的大小,该怎么办呢?
如果是你,你肯定已经想到了,对优化dockerfile,对的。那要怎么优化呢?
目前想到的方法:
1、在RUN的部分,先wget或者curl这个ROOT.war,然后再解压
2、多级构建
对,我们这里就是要用到方法2,多级构建来实现这个目标,为什么呢,因为,如果要wget,首先得有个http服务,对架构的要求又增加了。
那么,接下来,我们就来说说,如果要用多阶段构建的方式,如何来做······
3、多阶段构建
首先,多阶段构建是什么呢?
就是在dockerfile中,可以指定多个from指令,每个from都是一个新的构建阶段,后面的构建可以使用前面构建生成出来的镜像层或者说产物,这样就可以最大化的降低镜像的大小了。
口说无凭,来个例子。
我们把上面的dockerfile镜像修改:
FROM tomcat:9.0.53-jdk8u202-alpine as build #作为一个构建阶段,取名build ADD ROOT.war /usr/local/tomcat/webapps/ RUN cd /usr/local/tomcat/webapps/ && mkdir -p ROOT && unzip -o ROOT.war -d ROOT/ && rm -fr ROOT.war FROM tomcat:9.0.53-jdk8u202-alpine ADD uap-base_ypr.xml /var/ypr/ COPY --from=build /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT WORKDIR /usr/local/tomcat/webapps/
通过这个dockerfile,我们达到了如下的目标:
- build这个阶段的构建,将ROOT.war增加到容器,然后解压
- 在第2个FROM中创建了一个新的构建阶段,直接将前面的构建阶段中的解压好的ROOT目录拷贝到新的基础镜像中
- 前面的build中的ADD和解压,就变成了中间层
这样,最新的构建,就没有ADD ROOT.war这层了,直接使用前面中间的产物了。
到这里,结束了吗,当然没有,我们得构建,看看到底镜像的大小小了没有
docker build -t uap-base:0725 .
构建后查看镜像的大小:
果然,少了一个应用war包的大小。
看到这里,是不是觉得,多阶段构建,确实是如此的美妙,对于镜像层层数的优化,进而减少镜像的大小的作用立竿见影呢。
巧用多阶段构建,最大化的压缩、优化你的镜像的大小!还不快试试
揭示怎样仅仅通过阅读文章,就能每天赚到5000元现金!
该报告100%免费
所有你需要做的是,添加下面的微信,备注"免费报告"