SpringBoot-2-3-x分层构建Docker镜像实践,docker教程学习

2022年6月3日11:07:54

org.springframework.boot
spring-boot-maven-plugin

true

执行 Maven 命令,构建分层的 JAR 包,命令和平时的 Maven 构建命令相同:

$ mvn install

观察 Jar 结构,可以看到里面多了classpath.idx 与layers.idx 两个文件:

  • classpath.idx: 文件列出了依赖的 jar 包列表,到时候会按照这个顺序载入。
  • layers.idx: 文件清单,记录了所有要被复制到 Dokcer 镜像中的文件信息。

根据官方介绍,在构建 Docker 镜像前需要从 Jar 中提起出对应的分层文件到 Jar 外面,可用使用下面命令列出可以从分层 Jar 中提取出的文件夹信息:

$ java -Djarmode=layertools -jar target/springboot-layer-0.0.1.jar list

可用该看到以下输出,下面的内容就是接下来使用分层构建后,生成的 Jar 提取出对应资源后的结构:

dependencies
spring-boot-loader
snapshot-dependencies
application

上面即是使用分层工具提取 Jar 的内容后生成的文件夹,其中各个文件夹作用是:

  • dependencies: 存储项目正常依赖 Jar 的文件夹。
  • snapshot-dependencies: 存储项目快照依赖 Jar 的文件夹。
  • resources: 用于存储静态资源的文件夹。
  • application: 用于存储应用程序类相关文件的文件夹。

三、创建测试的 SpringBoot 应用

创建测试的 SpringBoot 项目,并且在 pom.xml 中开启镜像分层。

1、Maven 中引入相关依赖和插件

<?xml version="1.0" encoding="UTF-8"?>

4.0.0

org.springframework.boot spring-boot-starter-parent 2.3.6.RELEASE

springboot-dockerfile-layer
jar
springboot-dockerfile-layer
springboot build layer example

org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin true

2、创建测试的 Controller 类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

@GetMapping("/hello")
public String hello() {
return “hello world!”;
}

}

3、创建 SpringBoot 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

四、创建两种构建镜像的 Dockerfile 脚本

为了方便体现出 SpringBoot 2.3.x 支持的分层构建 Dockerfile 的优点,这里在 Java 源码文件夹下,创建普通与分层两种构建镜像的 Dockerfile 脚本,后续会使用这两种脚本构建 Docker 镜像进行构建速度、推送速度、拉取速度的对比。

1、普通镜像构建脚本文件 dockerfile-number

FROM openjdk:8u275
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c ‘touch /app.jar’
ENV TZ=“Asia/Shanghai”
RUN ln -snf /usr/share/zoneinfo/KaTeX parse error: Expected 'EOF', got '&' at position 19: …/etc/localtime &̲& echoTZ > /etc/timezone
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENV JAVA_OPTS=""
ENTRYPOINT [ “sh”, “-c”, “java

J

A

V

A

O

P

T

S

 

D

j

a

v

a

.

s

e

c

u

r

i

t

y

.

e

g

d

=

f

i

l

e

:

/

d

e

v

/

.

/

u

r

a

n

d

o

m

 

j

a

r

 

/

a

p

p

.

j

a

r

 

JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jarJAVAOPTSDjava.security.egd=file:/dev/./urandomjar/app.jarAPP_OPTS” ]

说明:

  • TZ: 时区设置,而 Asia/Shanghai 表示使用中国上海时区。
  • JVM_OPTS: 指定 JVM 启动时候的参数,-XX:MaxRAMPercentage 参数和 -Xmx 类似,都是限制堆内存大小,只不过 -Xmx 需要手动指定限制大小,而 -XX:MaxRAMPercentage 则是根据虚拟机可用内存百分比限制。
  • JAVA_OPTS: 在镜像启动时指定的自定义 Java 参数,例如 -Dspring.application.name=xxx。

2、分层镜像构建脚本文件 dockerfile-layer

FROM openjdk:8u275 as builder
WORKDIR application
COPY target/*.jar application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM openjdk:8u275
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/application/ ./
ENV TZ=“Asia/Shanghai”
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENV JAVA_OPTS=""
ENTRYPOINT

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

[“sh”,"-c",“java

J

V

M

O

P

T

S

 

JVM_OPTSJVMOPTSJAVA_OPTS org.springframework.boot.loader.JarLauncher”]

说明:

  • TZ: 时区设置,而 Asia/Shanghai 表示使用中国上海时区。
  • -Djarmode=layertools: 指定构建 Jar 的模式。
  • extract: 从 Jar 包中提取构建镜像所需的内容。
  • -from=builder 多级镜像构建中,从上一级镜像复制文件到当前镜像中。

五、使用两种 Dockerfile 构建项目镜像

1、在服务器一构建普通 Docker 镜像

(1)、第一次构建

## 执行 Maven 命令,将源代码构建 Jar 包
$ mvn clean install

## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.1 .

Docker 镜像构建总共花费 24.98s 时间。

(2)、第二次构建(修改依赖 pom.xml 文件)

## 修改 pom.xml 里面的依赖,随意添加一个新的依赖包,然后再次将源代码构建 Jar 包
$ mvn clean install

## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.2 .

Docker 镜像构建总共花费 1.27s 时间。

(3)、第三次构建(修改代码内容)

## 修改源代码任意内容后,然后再次将源代码构建 Jar 包
$ mvn clean install

## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.3 .

Docker 镜像构建总共花费 1.32s 时间。

2、在服务器二构建分层 Docker 镜像

(1)、第一次构建

## 执行 Maven 命令,将源代码构建 Jar 包
$ mvn clean install

## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.1 .

Docker 镜像构建总共花费 26.12s 时间。

(2)、第二次构建(修改依赖 pom.xml 文件)

## 修改 pom.xml 里面的依赖,随意添加一个新的依赖包,然后再次将源代码构建 Jar 包
$ mvn clean install

## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.2 .

Docker 镜像构建总共花费 3.44s 时间。

(3)、第三次构建(修改代码内容)

## 修改源代码任意内容后,然后再次将源代码构建 Jar 包
$ mvn clean install

## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.3 .

Docker 镜像构建总共花费 2.82s 时间。

六、镜像推送到镜像仓库测试

1、推送镜像到镜像仓库测试

服务器一推送普通镜像到镜像仓库1:

## 第一次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1

real    0m35.215s

## 第二次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2

real    0m14.051s

## 第三次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3

real    0m14.183s

服务器二推送分层镜像到镜像仓库2:

## 第一次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.1

real    0m34.121s

## 第二次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.2

real    0m13.605s

## 第三次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.3

real    0m4.805s

2、镜像仓库拉取镜像测试

服务器一推送从镜像仓库1拉取镜像:

## 清理全部镜像

 

d

o

c

k

e

r

 

r

m

 

f

o

r

c

e

 

 docker rm --forcedockerrmforce(docker images -qa)

## 拉取镜像 springboot-normal:0.0.1
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1

real    0m35.395s

## 拉取镜像 springboot-normal:0.0.2
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2

real    0m6.501s

## 拉取镜像 springboot-normal:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3

real    0m6.993s

服务器二推送从镜像仓库2拉取镜像:

## 清理全部镜像

 

d

o

c

k

e

r

 

r

m

 

f

o

r

c

e

 

 docker rm --forcedockerrmforce(docker images -qa)

## 拉取镜像 springboot-layer:0.0.1
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1

real    0m30.615s

## 拉取镜像 springboot-layer:0.0.2
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2

real    0m4.811s

## 拉取镜像 springboot-layer:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3

real    0m1.293s

七、镜像构建、推送、拉取时间汇总

1、不使用分层构建镜像

SpringBoot-2-3-x分层构建Docker镜像实践,docker教程学习

如下图:

SpringBoot-2-3-x分层构建Docker镜像实践,docker教程学习

2、使用分层构建镜像

SpringBoot-2-3-x分层构建Docker镜像实践,docker教程学习

如下图:

SpringBoot-2-3-x分层构建Docker镜像实践,docker教程学习

3、总结

## 拉取镜像 springboot-layer:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3

real    0m1.293s

七、镜像构建、推送、拉取时间汇总

1、不使用分层构建镜像

[外链图片转存中…(img-DV3xEn12-1640329301916)]

如下图:

[外链图片转存中…(img-qNiVHvET-1640329301948)]

2、使用分层构建镜像

[外链图片转存中…(img-jIkMGQm5-1640329301949)]

如下图:

[外链图片转存中…(img-bQ94zma0-1640329301950)]


  • 作者:普通网友
  • 原文链接:https://blog.csdn.net/m0_65321095/article/details/122128436
    更新时间:2022年6月3日11:07:54 ,共 6309 字。