详解SpringBoot(2.3)应用制作Docker镜像(官方方案)

简介: 学习SpringBoot官方镜像方案的细节

欢迎访问我的GitHub

关于《SpringBoot-2.3容器化技术》系列

  • 《SpringBoot-2.3容器化技术》系列,旨在和大家一起学习实践2.3版本带来的最新容器化技术,让咱们的Java应用更加适应容器化环境,在云计算时代依旧紧跟主流,保持竞争力;
  • 全系列文章分为主题和辅助两部分,主题部分如下:
  1. 《体验SpringBoot(2.3)应用制作Docker镜像(官方方案)》
  2. 《详解SpringBoot(2.3)应用制作Docker镜像(官方方案)》
  3. 《掌握SpringBoot-2.3的容器探针:基础篇》
  4. 《掌握SpringBoot-2.3的容器探针:深入篇》
  5. 《掌握SpringBoot-2.3的容器探针:实战篇》
  • 辅助部分是一些参考资料和备忘总结,如下:
  1. 《SpringBoot-2.3镜像方案为什么要做多个layer》
  2. 《设置非root账号不用sudo直接执行docker命令》
  3. 《开发阶段,将SpringBoot应用快速部署到K8S》

本篇简介

前文,咱们快速体验了官方推荐的docker镜像制作方案,但也产生了几个疑问:

  1. SpringBoot-2.3版本推荐的镜像构建方案和旧版本比有什么不同?
  2. pom.xml中spring-boot-maven-plugin插件新增的参数,到底做了什么?
  3. Dockerfile中,java -Djarmode=layertools -jar application.jar extract这个操作啥意思?

本篇的目标就是解答上述问题,在寻找答案的过程中不断补全知识点,提升自己;

关键知识点:镜像layer

前文多次提到的镜像layer到底是什么,为什么会有多层layer?有必要先把这个知识点夯实了,请参考文章《SpringBoot-2.3镜像方案为什么要做多个layer》

老版本SpringBoot的官方方案

SpringBoot-2.2.0.RELEASE版本为例,官方文档(
https: //docs.spring.io/spring-boot/docs/2.2.0.RELEASE/reference/pdf/spring-boot-reference.pdf)给出的做法如下:

  1. 将SpringBoot工程编译构建,在target目录得到jar;
  2. 在target目录新建dependency文件夹;
  3. 将jar解压到dependency文件夹;
  4. 编写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"]
  1. 可见,官方推荐的做法是将整个jar文件解压,在Dockerfile中多次用COPY命令分别复制,这样做的好处显而易见:多个layer,如果镜像的新版本中只修改了应用代码,那么下载镜像时只会下载/app这个layer,其他部分直接使用本地缓存,这是docker镜像的常规优化手段;
  2. 上述方案有个小问题:麻烦!!!
  3. 于是2.3.0.RELEASE版本做了些优化,让事情变得简单些;

2.3.0.RELEASE版本方案和旧版的区别

2.3.0.RELEASE版本构建Docker的步骤如下:

  1. pom.xml中的spring-boot-maven-plugin插件增加一个配置项;

2.编译构建生成jar;

  1. 编写Dockerfile,里面用到了多阶段构建(multi-stage builds),用工具从jar中提取拆分后,再多次执行COPY命令将拆分后的内容放入镜像,达到多个layer的目的;

因此,2.3.0.RELEASE版本和旧版本相比有如下变化:

  1. pom.xml中多了个参数;
  2. 构建好jar后,无需自己解压jar;
  3. Dockefile内容不一样,旧版是手动解压jar,再在Dockerfile分别复制,2.3.0.RELEASE是通过java命令从jar中提取出各部分内容

搞清楚了新旧版本的区别,咱们继续研究下一个问题吧;

pom.xml中spring-boot-maven-plugin插件新增的参数

  1. pring-boot-maven-plugin插件新增参数如下图所示:

在这里插入图片描述

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

在这里插入图片描述

  1. 看看layers.idx文件的内容,如下图:

在这里插入图片描述

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

在这里插入图片描述

  1. 综上所述,layers.idx文件是个清单,里面记录了所有要被复制到镜像中的信息,接下来看看如何使用layers.idx文件,这就涉及到jar包中新增的另一个文件:spring-boot-jarmode-layertools-2.3.0.RELEASE.jar

spring-boot-jarmode-layertools工具

  1. 前面已经介绍过jar中除了layers.idx,还多了个文件:spring-boot-jarmode-layertools-2.3.0.RELEASE.jar ,来看看这个文件的用处;
  2. 进入工程的target目录,这里面是编译后的jar文件(我这里文件名为dockerlayerdemo-0.0.1-SNAPSHOT.jar),注意此时的spring-boot-maven-plugin插件是带上了下图红框中的参数的:

在这里插入图片描述

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

在这里插入图片描述

  1. 来看看官方对这个layertools的解释,list参数的作用上面我们已经体验过了,重点是红框中的extract参数,它的作用是从jar中提取构建镜像所需的内容:

在这里插入图片描述

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

在这里插入图片描述
至此,三个问题都已经找到了答案,小结一下:

SpringBoot-2.3.0.RELEASE推荐的镜像构建方案和旧版本相比有什么不同

  1. pom.xml中的spring-boot-maven-plugin插件增加一个配置项;
  2. 构建好jar后,旧版本要自己解压jar,新版不需要;
  3. 新版本的jar中,多了个文件清单layers.idx和镜像文件处理工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar
  4. 旧版的Dockefile内容:因为前面解压好了,所有在Dockerfile里直接复制前面解压的内容,这里就有个风险:前一步解压和当前复制的文件位置要保证一致;
  5. 新版的Dockerfile内容:使用工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar,根据的layers.idx内容从jar中提取文件,复制到镜像中;
  6. 新版的Dockerfile中,由于使用了分阶段构建,因此从jar提取文件的操作不会保存到镜像的layer中;

pom.xml中spring-boot-maven-plugin插件新增的参数,到底做了什么

spring-boot-maven-plugin插件新增的参数,使得编译构建得到jar中多了两个文件,如下图所示:
在这里插入图片描述

Dockerfile中,java -Djarmode=layertools -jar application.jar extract这个操作啥意思

  1. java -Djarmode=layertools -jar application.jar extract的作用是从jar中提取文件,这些文件是docker镜像的一部分;
  2. 上述操作的参数是extract,另外还有两个参数,官方解释它们的作用如下:

在这里插入图片描述
至此,问题已全部澄清,相信您对SpringBoot-2.3.0.RELEASE官方的镜像构建方案也足够了解了,最后是我根据自己的认识画的流程图,帮助您快速理解整个构建流程:
在这里插入图片描述

欢迎访问我的GitHub

欢迎关注阿里云开发者社区:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关文章
|
6天前
|
Ubuntu NoSQL 开发工具
《docker基础篇:4.Docker镜像》包括是什么、分层的镜像、UnionFS(联合文件系统)、docker镜像的加载原理、为什么docker镜像要采用这种分层结构呢、docker镜像commit
《docker基础篇:4.Docker镜像》包括是什么、分层的镜像、UnionFS(联合文件系统)、docker镜像的加载原理、为什么docker镜像要采用这种分层结构呢、docker镜像commit
120 70
|
5天前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
52 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
8天前
|
Ubuntu NoSQL 关系型数据库
《docker基础篇:6.本地镜像发布到私有库》包括本地镜像发布到私有库流程、docker regisry是什么、将本地镜像推送到私有库
《docker基础篇:6.本地镜像发布到私有库》包括本地镜像发布到私有库流程、docker regisry是什么、将本地镜像推送到私有库
70 29
|
1月前
|
Docker 容器
将本地的应用程序打包成Docker镜像
将本地的应用程序打包成Docker镜像
|
27天前
|
NoSQL PHP MongoDB
docker push推送自己搭建的镜像
本文详细介绍了如何搭建和复盘两个Web安全挑战环境:人力资源管理系统和邮件管理系统。首先,通过Docker搭建MongoDB和PHP环境,模拟人力资源管理系统的漏洞,包括nosql注入和文件写入等。接着,复盘了如何利用这些漏洞获取flag。邮件管理系统部分,通过目录遍历、文件恢复和字符串比较等技术,逐步绕过验证并最终获取flag。文章提供了详细的步骤和代码示例,适合安全研究人员学习和实践。
48 3
docker push推送自己搭建的镜像
|
1月前
|
Docker 容器
|
1月前
|
数据库 Docker 容器
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
70 9
|
1月前
|
Java 应用服务中间件 Docker
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
41 2
|
域名解析 NoSQL Java
Springboot docker jenkins 自动化部署并上传镜像
本文为大家讲解Springboot docker jenkins 自动化部署并上传镜像的过程。
3696 0
Springboot docker jenkins 自动化部署并上传镜像
|
3月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
212 1