关于《SpringBoot-2.3容器化技术》系列
《SpringBoot-2.3容器化技术》系列,旨在和你们一块儿学习实践2.3版本带来的最新容器化技术,让我们的Java应用更加适应容器化环境,在云计算时代依旧紧跟主流,保持竞争力;java
全系列文章分为主题和辅助两部分,主题部分以下:git
- 《体验SpringBoot(2.3)应用制做Docker镜像(官方方案)》;
- 《详解SpringBoot(2.3)应用制做Docker镜像(官方方案)》;
- 《掌握SpringBoot-2.3的容器探针:基础篇》;
- 《掌握SpringBoot-2.3的容器探针:深刻篇》;
- 《掌握SpringBoot-2.3的容器探针:实战篇》;
辅助部分是一些参考资料和备忘总结,以下:程序员
- 《SpringBoot-2.3镜像方案为何要作多个layer》;
- 《设置非root帐号不用sudo直接执行docker命令》;
- 《开发阶段,将SpringBoot应用快速部署到K8S》;
本篇简介
在前文,我们快速体验了官方推荐的docker镜像制做方案,但也产生了几个疑问:github
- SpringBoot-2.3版本推荐的镜像构建方案和旧版本比有什么不一样?
- pom.xml中<font color="blue">spring-boot-maven-plugin</font>插件新增的参数,到底作了什么?
- Dockerfile中,<font color="blue">java -Djarmode=layertools -jar application.jar extract</font>这个操做啥意思?
本篇的目标就是解答上述问题,在寻找答案的过程当中不断补全知识点,提高本身;spring
关键知识点:镜像layer
前文屡次提到的镜像layer究竟是什么,为何会有多层layer?有必要先把这个知识点夯实了,请参考文章《SpringBoot-2.3镜像方案为何要作多个layer》docker
老版本SpringBoot的官方方案
以<font color="blue">SpringBoot-2.2.0.RELEASE</font>版本为例,官方文档(
https://docs.spring.io/spring...:shell
- 将SpringBoot工程编译构建,在target目录获得jar;
- 在target目录新建dependency文件夹;
- 将jar解压到dependency文件夹;
- 编写Dockerfile文件,内容以下:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.MyApplication"]
- 可见,官方推荐的作法是将整个jar文件解压,在Dockerfile中屡次用COPY命令分别复制,这样作的好处显而易见:多个layer,若是镜像的新版本中只修改了应用代码,那么下载镜像时只会下载/app这个layer,其余部分直接使用本地缓存,这是docker镜像的常规优化手段;
- 上述方案有个小问题:<font color="red">麻烦!!!</font>
- 因而2.3.0.RELEASE版本作了些优化,让事情变得简单些;
2.3.0.RELEASE版本方案和旧版的区别
2.3.0.RELEASE版本构建Docker的步骤以下:缓存
- pom.xml中的spring-boot-maven-plugin插件增长一个配置项;
2.编译构建生成jar;app
- 编写Dockerfile,里面用到了多阶段构建(multi-stage builds),用工具从jar中提取拆分后,再屡次执行COPY命令将拆分后的内容放入镜像,达到多个layer的目的;
所以,2.3.0.RELEASE版本和旧版本相比有以下变化:maven
- <font color="blue">pom.xml</font>中多了个参数;
- 构建好jar后,无需本身解压jar;
- Dockefile内容不同,旧版是手动解压jar,再在Dockerfile分别复制,2.3.0.RELEASE是经过<font color="red">java命令从jar中提取出各部份内容</font>;
搞清楚了新旧版本的区别,我们继续研究下一个问题吧;
pom.xml中spring-boot-maven-plugin插件新增的参数
- pring-boot-maven-plugin插件新增参数以下图所示:

- 上述参数有啥用?我这边编译构建了两次jar,第一次有上述参数,第二次没有,将两次生成的jar解压后对比,发现用了上述参数后,生成的jar会多出下图红框中的两个文件:

- 看看<font color="blue">layers.idx</font>文件的内容,以下图:

- 上图中的内容分别是什么意思呢?官方已给出了详细解释,以下图红框:

- 综上所述,layers.idx文件是个清单,里面记录了全部要被复制到镜像中的信息,接下来看看如何使用layers.idx文件,这就涉及到jar包中新增的另外一个文件:<font color="blue">spring-boot-jarmode-layertools-2.3.0.RELEASE.jar</font>
spring-boot-jarmode-layertools工具
- 前面已经介绍过jar中除了layers.idx,还多了个文件:<font color="blue">spring-boot-jarmode-layertools-2.3.0.RELEASE.jar</font> ,来看看这个文件的用处;
- 进入工程的<font color="blue">target</font>目录,这里面是编译后的jar文件(我这里文件名为dockerlayerdemo-0.0.1-SNAPSHOT.jar),注意此时的<font color="blue">spring-boot-maven-plugin</font>插件是带上了下图红框中的参数的:

- 执行如下命令:
java -Djarmode=layertools -jar dockerlayerdemo-0.0.1-SNAPSHOT.jar list
- 获得结果以下图所示,是layers.idx文件的内容:

- 来看看官方对这个<font color="blue">layertools</font>的解释,list参数的做用上面咱们已经体验过了,重点是红框中的<font color="red">extract</font>参数,它的做用是从jar中提取构建镜像所需的内容:

- 看到这里,您是否想到了《体验SpringBoot(2.3)应用制做Docker镜像(官方方案)》中Dockerfile的内容,请看下图的红框和红字,是否有种恍然大悟的感受:jar构建生成清单layers.idx,Dockerfile中根据清单从jar提取文件放入镜像:

至此,三个问题都已经找到了答案,小结一下:
SpringBoot-2.3.0.RELEASE推荐的镜像构建方案和旧版本相比有什么不一样
- pom.xml中的spring-boot-maven-plugin插件增长一个配置项;
- 构建好jar后,旧版本要本身解压jar,新版不须要;
- 新版本的jar中,多了个文件清单<font color="blue">layers.idx</font>和镜像文件处理工具<font color="blue">spring-boot-jarmode-layertools-2.3.0.RELEASE.jar</font>;
- 旧版的Dockefile内容:由于前面解压好了,全部在Dockerfile里直接复制前面解压的内容,这里就有个风险:前一步解压和当前复制的文件位置要保证一致;
- 新版的Dockerfile内容:使用工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar,根据的layers.idx内容从jar中提取文件,复制到镜像中;
- 新版的Dockerfile中,因为使用了分阶段构建,所以从jar提取文件的操做不会保存到镜像的layer中;
pom.xml中spring-boot-maven-plugin插件新增的参数,到底作了什么
spring-boot-maven-plugin插件新增的参数,使得编译构建获得jar中多了两个文件,以下图所示:

Dockerfile中,java -Djarmode=layertools -jar application.jar extract这个操做啥意思
- <font color="blue">java -Djarmode=layertools -jar application.jar extract</font>的做用是从jar中提取文件,这些文件是docker镜像的一部分;
- 上述操做的参数是<font color="blue">extract</font>,另外还有两个参数,官方解释它们的做用以下:

至此,问题已所有澄清,相信您对SpringBoot-2.3.0.RELEASE官方的镜像构建方案也足够了解了,最后是我根据本身的认识画的流程图,帮助您快速理解整个构建流程:

欢迎访问个人GitHub
欢迎关注个人公众号:程序员欣宸

https://github.com/zq2599/blog_demos