拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 通过Spring Boot重用Docker层

通过Spring Boot重用Docker层

白鹭 - 2021-11-24 784 0 0

1.简介

Docker是用于创建自包含应用程序的事实上的标准。从2.3.0版开始,Spring Boot包括多项增强功能,可帮助我们创建高效的Docker映像。因此,它允许将应用程序分解为不同的层

换句话说,源代码驻留在其自己的层中。因此,它可以独立重建,从而提高了效率和启动时间。在本教程中,我们将看到如何利用Spring Boot的新功能来重用Docker层。

2. Docker中的分层罐

Docker容器由基本映像和附加层组成。构建图层后,它们将保持缓存状态。因此,后代将更快:

通过Spring

下层的更改也会重建上层的更改。因此,不经常变化的层应该保留在底部,而经常变化的层应该放置在顶部。

以同样的方式,Spring Boot允许将工件的内容映射到层中。让我们看一下默认的图层映射:

通过Spring

如我们所见,应用程序具有其自己的层。修改源代码时,仅重建独立层。加载程序和依赖项将保留在缓存中,从而减少了Docker映像的创建和启动时间。让我们看看如何用Spring Boot做到这一点!

3.使用Spring Boot创建高效的Docker映像

在传统的构建Docker映像的方式中,Spring Boot使用fat jar方法。结果,单个工件嵌入了所有依赖项和应用程序源代码。因此,源代码中的任何更改都将强制重建整个层。

3.1。使用Spring Boot进行层配置

Spring Boot版本2.3.0引入了两个新功能,以改善Docker映像的生成:

  • Buildpack支持为应用程序提供了Java运行时,因此现在可以跳过Dockerfile并自动构建Docker映像
  • 分层jar可帮助我们充分利用Docker层生成

在本教程中,我们将扩展分层jar方法。

最初,我们将在Maven中设置分层的jar。打包工件时,我们将生成图层。让我们检查一下jar文件:

jar tf target/spring-boot-docker-0.0.1-SNAPSHOT.jar

如我们所见,在胖罐子内的BOOT-INF文件夹中创建了.idx当然,它将依赖关系,资源和应用程序源代码映射到独立的层:

BOOT-INF/layers.idx

同样,文件的内容分解了存储的不同层:

- "dependencies":

    - "BOOT-INF/lib/"

 - "spring-boot-loader":

    - "org/"

 - "snapshot-dependencies":

 - "application":

    - "BOOT-INF/classes/"

    - "BOOT-INF/classpath.idx"

    - "BOOT-INF/layers.idx"

    - "META-INF/"

3.2。与图层互动

让我们列出工件内部的层:

java -Djarmode=layertools -jar target/docker-spring-boot-0.0.1.jar list

layers.idx文件内容的简单视图:

dependencies

 spring-boot-loader

 snapshot-dependencies

 application

我们还可以将图层提取到文件夹中:

java -Djarmode=layertools -jar target/docker-spring-boot-0.0.1.jar extract

然后,我们可以重用Dockerfile内的文件夹,如我们在下一部分中将看到的:

$ ls

 application/

 snapshot-dependencies/

 dependencies/

 spring-boot-loader/

3.3。 Dockerfile配置

为了充分利用Docker功能,我们需要在图像中添加各层。

首先,让我们将胖子jar文件添加到基本映像中:

FROM adoptopenjdk:11-jre-hotspot as builder

 ARG JAR_FILE=target/*.jar

 COPY ${JAR_FILE} application.jar

其次,让我们提取工件的各层:

RUN java -Djarmode=layertools -jar application.jar extract

最后,让我们复制提取的文件夹以添加相应的Docker层:

FROM adoptopenjdk:11-jre-hotspot

 COPY --from=builder dependencies/ ./

 COPY --from=builder snapshot-dependencies/ ./

 COPY --from=builder spring-boot-loader/ ./

 COPY --from=builder application/ ./

 ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

通过这种配置,当我们更改源代码时,我们将仅重建应用程序层。其余的将保留在缓存中。

4.自定义层

似乎一切都像魅力一样运作。但是,如果仔细看,依赖关系层不会在内部版本之间共享。就是说,所有这些都进入了一个单一的层,甚至是内部层。因此,如果更改内部库的类,则将再次重建所有依赖关系层。

4.1。使用Spring Boot的自定义层配置

在Spring Boot中,可以通过单独的配置文件来调整自定义图层:

<layers xmlns="http://www.springframework.org/schema/boot/layers"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://www.springframework.org/schema/boot/layers

 https://www.springframework.org/schema/boot/layers/layers-2.3.xsd">

 <application>

 <into layer="spring-boot-loader">

 <include>org/springframework/boot/loader/**</include>

 </into>

 <into layer="application" />

 </application>

 <dependencies>

 <into layer="snapshot-dependencies">

 <include>*:*:*SNAPSHOT</include>

 </into>

 <into layer="dependencies" />

 </dependencies>

 <layerOrder>

 <layer>dependencies</layer>

 <layer>spring-boot-loader</layer>

 <layer>snapshot-dependencies</layer>

 <layer>application</layer>

 </layerOrder>

 </layers>

如我们所见,我们正在将依赖关系和资源映射并排序到层中。此外,我们可以根据需要添加任意数量的自定义图层。

让我们将文件layers.xml 。然后,在Maven中,我们可以配置此文件以自定义图层:

<plugin>

 <groupId>org.springframework.boot</groupId>

 <artifactId>spring-boot-maven-plugin</artifactId>

 <configuration>

 <layers>

 <enabled>true</enabled>

 <configuration>${project.basedir}/src/layers.xml</configuration>

 </layers>

 </configuration>

 </plugin>

如果我们打包工件,结果将类似于默认行为。

4.2。添加新层

让我们创建一个内部依赖项,添加我们的应用程序类:

<into layer="internal-dependencies">

 <include>com.baeldung.docker:*:*</include>

 </into>

此外,我们将订购新层:

<layerOrder>

 <layer>internal-dependencies</layer>

 </layerOrder>

结果,如果我们列出胖子罐中的各层,则会出现新的内部依赖项:

dependencies

 spring-boot-loader

 internal-dependencies

 snapshot-dependencies

 application

4.3。 Dockerfile配置

提取后,我们可以将新的内部层添加到我们的Docker映像中:

COPY --from=builder internal-dependencies/ ./

因此,如果我们生成图像,我们将看到Docker如何将内部依赖项作为新层构建:

$ mvn package

 $ docker build -f src/main/docker/Dockerfile . --tag spring-docker-demo

 ....

 Step 8/11 : COPY --from=builder internal-dependencies/ ./

 ---> 0e138e074118

 .....

之后,我们可以在历史记录中检查Docker映像中各层的组成:

$ docker history --format "{{.ID}} {{.CreatedBy}} {{.Size}}" spring-docker-demo

 c0d77f6af917 /bin/sh -c #(nop) ENTRYPOINT ["java" "org.s… 0B

 762598a32eb7 /bin/sh -c #(nop) COPY dir:a87b8823d5125bcc4… 7.42kB

 80a00930350f /bin/sh -c #(nop) COPY dir:3875f37b8a0ed7494… 0B

 0e138e074118 /bin/sh -c #(nop) COPY dir:db6f791338cb4f209… 2.35kB

 e079ad66e67b /bin/sh -c #(nop) COPY dir:92a8a991992e9a488… 235kB

 77a9401bd813 /bin/sh -c #(nop) COPY dir:f0bcb2a510eef53a7… 16.4MB

 2eb37d403188 /bin/sh -c #(nop) ENV JAVA_HOME=/opt/java/o… 0B

如我们所见,该层现在包括项目的内部依赖项。

5.结论

在本教程中,我们展示了如何生成有效的Docker映像。简而言之,我们使用了新的Spring Boot功能来创建分层的jar。对于简单的项目,我们可以使用默认配置。我们还展示了一种更高级的配置以重用这些层。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *