一、场景

最常见的是容器镜像,将依赖、代码、配置分层后可以利用容器镜像层缓存机制加快构建和下载,这个场景使用分层是最优最简单的。

k8s 移除 Docker 后,文档中的 Docker 都去掉了…现在也把常说的Docker 镜像 改成了容器镜像

二、分层配置

如果不需要自定义分层,这一步可以跳过

在项目根目录中添加layers.xml 配置文件,文件内容如下:

<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.6.xsd">     <application>         <into layer="spring-boot-loader">             <include>org/springframework/boot/loader/**</include>         </into>         <into layer="application"/>     </application>     <dependencies>         <into layer="application">             <includeModuleDependencies/>         </into>         <into layer="snapshot-dependencies">             <include>*:*:*SNAPSHOT</include>         </into>         <into layer="sencond-dependencies">             <include>com.example:*:*</include>         </into>         <into layer="dependencies"/>     </dependencies>     <layerOrder>         <layer>dependencies</layer>         <layer>spring-boot-loader</layer>         <layer>sencond-dependencies</layer>         <layer>snapshot-dependencies</layer>         <layer>application</layer>     </layerOrder> </layers>

和官方示例相比这里增加了sencond-dependencies ,算是二方库依赖,如果公司有自己框架,自己平台,根据依赖的稳定性(修改频率)进行更细的分层。

依赖分层设计,可以参考企业 Maven 依赖管理层次结构设计 。

使用 IDEA,并且下载layers-2.6.xsd 的情况下,<includeModuleDependencies/> 会报红,如下图所示:

通过查看官方文档和 spring boot 代码,发现文档、代码和 xsd 定义存在不一致的地方,提了issues#31115 、pr#31117pr#31126 ,代码已经合并, xsd经过修改,和文档保持一致。

增加上面的配置后,修改插件使用该配置:

<plugin>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-maven-plugin</artifactId>     <version>${spring-boot.version}</version>     <executions>         <execution>             <id>repackage</id>             <goals>                 <goal>repackage</goal>             </goals>         </execution>     </executions>     <configuration>         <layers>             <enabled>true</enabled>             <configuration>${project.basedir}/layers.xml</configuration>         </layers>     </configuration> </plugin>

三、容器镜像

构建镜像有多种方式,官方文档介绍了 Dockerfile 和 Buildpacks 两种。

3.1 Dockerfile

通过layertools 可以将 fat jar 按照分层定义中的层进行解压,命令如下:

Usage:   java -Djarmode=layertools -jar my-app.jar  Available commands:   list     List layers from the jar that can be extracted   extract  Extracts layers from the jar for image creation   help     Help about any command

通过java -Djarmode=layertools -jar my-app.jar extract 即可解压 jar 包到当前目录。为了方便,可以直接通过 Dockerfile 的多阶段构建进行,Dockerfile 如下:

FROM eclipse-temurin:11-jre as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract  FROM eclipse-temurin:11-jre WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

如果有自定义分层,记得按顺序加入到 COPY 部分

一般情况下 target 下面只有一个 jar 后缀的包,此时可以直接执行下面的 Docker 命令:

docker build --tag imageName:version .

如果有多个 jar,需要通过参数指定:

docker build  --build-arg JAR_FILE=path/to/myapp.jar --tag imageName:version .

构建后查看镜像信息:

IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT e1d22f48893d   11 seconds ago   ENTRYPOINT ["java" "org.springframework.boot…   0B        buildkit.dockerfile.v0 <missing>      11 seconds ago   COPY application/application/ ./ # buildkit     55.1kB    buildkit.dockerfile.v0 <missing>      11 seconds ago   COPY application/snapshot-dependencies/ ./ #…   46.1MB    buildkit.dockerfile.v0 <missing>      12 seconds ago   COPY application/spring-boot-loader/ ./ # bu…   252kB     buildkit.dockerfile.v0 <missing>      12 seconds ago   COPY application/dependencies/ ./ # buildkit    216MB     buildkit.dockerfile.v0 <missing>      10 minutes ago   WORKDIR /application                            0B        buildkit.dockerfile.v0 <missing>      2 months ago     /bin/sh -c set -eux;   arch="$(dpkg --print-…   210MB      <missing>      2 months ago     /bin/sh -c #(nop)  ENV JAVA_VERSION=8u322       0B         <missing>      2 months ago     /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B         <missing>      2 months ago     /bin/sh -c #(nop)  ENV PATH=/usr/local/openj…   0B         <missing>      2 months ago     /bin/sh -c { echo '#/bin/sh'; echo 'echo "$J…   27B        <missing>      2 months ago     /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/local/…   0B         <missing>      2 months ago     /bin/sh -c set -eux;  apt-get update;  apt-g…   4.88MB     <missing>      2 months ago     /bin/sh -c #(nop)  CMD ["bash"]                 0B         <missing>      2 months ago     /bin/sh -c #(nop) ADD file:d48a85028743f16ed…   80.4MB

层信息:

"RootFS": {       "Type": "layers",     "Layers": [         "sha256:1401df2b50d5de5a743b7bac3238ef3b7ce905ae39f54707b0ebb8eda3ab10bc",         "sha256:43015d7c36457e91ff0994082e7016335d5aa7690e8b5c799d41c2bab47f086c",         "sha256:f1bceed991c5891bd4bf3ad6e1ade5334e2c40ada40305b59fbf0a275ebbed17",         "sha256:7a49a2f5a65e2f57886dd32ffe85542283b249ccefd7a1b5379632030912d804",         "sha256:8791c93670dee0e973efce4424ea9b33caa49e7ef15c8e0bde1912b51c349524",         "sha256:94c6796cee53f42ae2478affbfc8510c97c76e65015ec46309f83265df078ef8",         "sha256:033be8a54968fe881ce71510862eacc0c3f3bdb6eb2af1a9130704bbe7442ae8",         "sha256:ab0700832472168ad4a9060b3fbedf8cc44f22ff1d074aebb67d9ee466796515",         "sha256:06a62903d01189112c0c8b6b68debaa170228e9d7cf868e1b9959001e877a4c4"     ] }

对代码进行简单修改后,重新构建镜像,再次查看:

IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT cc399ec3ba61   13 seconds ago   ENTRYPOINT ["java" "org.springframework.boot…   0B        buildkit.dockerfile.v0 <missing>      13 seconds ago   COPY application/application/ ./ # buildkit     52.9kB    buildkit.dockerfile.v0 <missing>      3 minutes ago    COPY application/snapshot-dependencies/ ./ #…   46.1MB    buildkit.dockerfile.v0 <missing>      3 minutes ago    COPY application/spring-boot-loader/ ./ # bu…   252kB     buildkit.dockerfile.v0 <missing>      3 minutes ago    COPY application/dependencies/ ./ # buildkit    216MB     buildkit.dockerfile.v0 <missing>      13 minutes ago   WORKDIR /application                            0B        buildkit.dockerfile.v0 <missing>      2 months ago     /bin/sh -c set -eux;   arch="$(dpkg --print-…   210MB      <missing>      2 months ago     /bin/sh -c #(nop)  ENV JAVA_VERSION=8u322       0B         <missing>      2 months ago     /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B         <missing>      2 months ago     /bin/sh -c #(nop)  ENV PATH=/usr/local/openj…   0B         <missing>      2 months ago     /bin/sh -c { echo '#/bin/sh'; echo 'echo "$J…   27B        <missing>      2 months ago     /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/local/…   0B         <missing>      2 months ago     /bin/sh -c set -eux;  apt-get update;  apt-g…   4.88MB     <missing>      2 months ago     /bin/sh -c #(nop)  CMD ["bash"]                 0B         <missing>      2 months ago     /bin/sh -c #(nop) ADD file:d48a85028743f16ed…   80.4MB

层信息:

"RootFS": {       "Type": "layers",     "Layers": [         "sha256:1401df2b50d5de5a743b7bac3238ef3b7ce905ae39f54707b0ebb8eda3ab10bc",         "sha256:43015d7c36457e91ff0994082e7016335d5aa7690e8b5c799d41c2bab47f086c",         "sha256:f1bceed991c5891bd4bf3ad6e1ade5334e2c40ada40305b59fbf0a275ebbed17",         "sha256:7a49a2f5a65e2f57886dd32ffe85542283b249ccefd7a1b5379632030912d804",         "sha256:8791c93670dee0e973efce4424ea9b33caa49e7ef15c8e0bde1912b51c349524",         "sha256:94c6796cee53f42ae2478affbfc8510c97c76e65015ec46309f83265df078ef8",         "sha256:033be8a54968fe881ce71510862eacc0c3f3bdb6eb2af1a9130704bbe7442ae8",         "sha256:ab0700832472168ad4a9060b3fbedf8cc44f22ff1d074aebb67d9ee466796515",         "sha256:4c0f187537195a34793722097d719f0c1247fec1648a6bdcf08f42556348af74"     ] }

和上面相比只有最上面的一层不同,通过分层尽可能利用Docker层缓存,可以减小镜像的差异,使得镜像更新时,只需要下载有差异的这一小部分。

构建镜像后,我们通过grype 检测镜像是否存在安全漏洞:

$ grype 镜像名:版本  ✔ Vulnerability DB        [no update available]  ✔ Loaded image              ✔ Parsed image              ✔ Cataloged packages      [521 packages]  ✔ Scanned image           [136 vulnerabilities]  NAME                           INSTALLED           FIXED-IN                 TYPE          VULNERABILITY        SEVERITY    apt                            2.2.4                                        deb           CVE-2011-3374        Negligible   aviator                        3.3.0                                        java-archive  GHSA-xpv2-8ppj-79hh  Critical     bsdutils                       1:2.36.1-8+deb11u1                           deb           CVE-2022-0563        Negligible   coreutils                      8.32-4+b1                                    deb           CVE-2017-18018       Negligible   coreutils                      8.32-4+b1           (won't fix)              deb           CVE-2016-2781        Low          e2fsprogs                      1.46.2-2            (won't fix)              deb           CVE-2022-1304        High         gzip                           1.10-4              1.10-4+deb11u1           deb           CVE-2022-1271        Unknown      libapt-pkg6.0                  2.2.4                                        deb           CVE-2011-3374        Negligible   ...

还可以对代码进行检查(dir:. 当前目录):

$ grype dir:.    ✔ Vulnerability DB        [no update available]  ✔ Indexed .                 ✔ Cataloged packages      [378 packages]  ✔ Scanned image           [36 vulnerabilities]  NAME                           INSTALLED     FIXED-IN      TYPE          VULNERABILITY        SEVERITY  aviator                        3.3.0                       java-archive  GHSA-xpv2-8ppj-79hh  Critical   maven-aether-provider          3.1.1                       java-archive  CVE-2021-26291       Critical   maven-artifact                 3.1.1                       java-archive  CVE-2021-26291       Critical   maven-common-artifact-filters  3.2.0                       java-archive  CVE-2021-26291       Critical   maven-core                     3.1.1                       java-archive  CVE-2021-26291       Critical   maven-model                    3.1.1                       java-archive  CVE-2021-26291       Critical   maven-model-builder            3.1.1                       java-archive  CVE-2021-26291       Critical   maven-repository-metadata      3.1.1                       java-archive  CVE-2021-26291       Critical   maven-settings                 3.1.1                       java-archive  CVE-2021-26291       Critical   maven-settings-builder         3.1.1                       java-archive  CVE-2021-26291       Critical   maven-shared-utils             3.3.3                       java-archive  CVE-2021-26291       Critical   minio                          8.3.8                       java-archive  CVE-2021-21390       Medium     minio                          8.3.8                       java-archive  CVE-2020-11012       High       minio                          8.3.8                       java-archive  CVE-2021-21287       High

3.2 Buildpacks

Spring Boot 插件集成了 Buildpacks 功能,插件配置如下:

<build>     <plugins>         <plugin>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-maven-plugin</artifactId>             <executions>                 <execution>                     <goals>                         <goal>build-image</goal>                     </goals>                 </execution>             </executions>         </plugin>     </plugins> </build>

执行mvn org.springframework.boot:spring-boot-maven-plugin:build-image 即可构建镜像。

构建完镜像后,运行时可能会遇到中文乱码,可以通过下面两种方式解决:

1 运行镜像时,通过环境变量指定编码:

docker run -e JAVA_OPTS="-Dfile.encoding=UTF-8" <image_name>

2 配置 spring boot 插件,添加默认的 JVM 配置:

<plugin>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-maven-plugin</artifactId>     <version>${spring-boot.version}</version>     <executions>         <execution>             <goals>                 <goal>build-image</goal>             </goals>         </execution>     </executions>     <configuration>         <image>             <env>                 <BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>                 <BPE_APPEND_JAVA_TOOL_OPTIONS>-Dfile.encoding=UTF-8</BPE_APPEND_JAVA_TOOL_OPTIONS>             </env>         </image>     </configuration> </plugin>

环境变量配置规则文档

GitHub - paketo-buildpacks/environment-variables: A Cloud Native Buildpack that embeds environment variables into an image

上面两个ENV配置介绍如下:

  1. 追加分隔符使用空格 ,xml配置保留空格(xml:space="preserve" )。
  2. 追加JVM参数

四、Jar 包运行

除了使用镜像外,当使用 Jar 包运行时,通过jar xf xxxx.jar 可以解压 jar 包到当前目录,解压后通过下面命令启动:

java org.springframework.boot.loader.JarLauncher

通过这种方式运行时,可以相对方便的修改配置文件,可以替换更新某些 jar 依赖,不用在对整个 fat jar 进行操作。

热门文章

11月27日更新21.1M/S,2024年最新高速SSR/Clash/Shadowrocket/V2ray订阅链接免费节点订阅

这一次的节点更新覆盖了日本、加拿大、香港、美国、欧洲、韩国、新加坡等地区,最高速度可达21.1 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

v-model.trim用法及其他修饰符

v-model的修饰符 v-model.lazy 只有在input输入框发生一个blur时才触发 v-model.trim 将用户输入的前后的空格去掉 v-model.number 将用户输入的字符串

1月27日更新22.9M/S,2025年最新高速Clash/V2ray/Shadowrocket/SSR订阅链接免费节点地址分享

这一次的节点更新覆盖了香港、新加坡、韩国、日本、美国、欧洲、加拿大等地区,最高速度可达22.9 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

上海宠物领养平台电话多少 上海宠物领养平台电话多少号

摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于上海宠物领养平台电话多少的问题,于是小编就整理了2个相关介绍上海宠物领养平台电话多少的解答,让我们一起看看吧。上海12378投诉

猫咪3针疫苗一共多少元冬天打(猫咪三针疫苗需要多久)

摘要: 本篇文章给大家谈谈猫咪3针疫苗一共多少元冬天打,以及猫咪三针疫苗需要多久对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、猫需要打几针疫苗?多少钱?...

宠物领养合同有法律效应吗 宠物领养合同有法律效应吗知乎

摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于宠物领养合同有法律效应吗的问题,于是小编就整理了5个相关介绍宠物领养合同有法律效应吗的解答,让我们一起看看吧。签订领养宠物协议靠

12月27日更新19M/S,2024年最新高速SSR/Shadowrocket/V2ray/Clash订阅链接免费节点地址分享

这一次的节点更新覆盖了香港、新加坡、韩国、日本、加拿大、美国、欧洲等地区,最高速度可达19 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

宠物领养什么意思啊(宠物领养须知)

摘要: 今天给各位分享宠物领养什么意思啊的知识,其中也会对宠物领养须知进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、拼多多领养是什么意思啊...

12月8日更新22.7M/S,2024年最新高速SSR/Shadowrocket/V2ray/Clash订阅链接免费节点订阅

这一次的节点更新覆盖了日本、韩国、加拿大、香港、新加坡、美国、欧洲等地区,最高速度可达22.7 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

内江宠物乐园哪家好(昆明宠物乐园哪家好)

摘要: 今天给各位分享内江宠物乐园哪家好的知识,其中也会对昆明宠物乐园哪家好进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、内江宠物交易市场在哪..

归纳