溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

發(fā)布時(shí)間:2021-12-10 13:08:02 來(lái)源:億速云 閱讀:268 作者:柒染 欄目:開(kāi)發(fā)技術(shù)

本篇文章給大家分享的是有關(guān)怎么進(jìn)行Spring Boot 分層打包Docker 鏡像實(shí)踐及分析,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

1. 準(zhǔn)備 spring boot 項(xiàng)目

簡(jiǎn)單,略過(guò)
spring boot 版本 > 2.3.x 即可
簡(jiǎn)單寫(xiě)了一個(gè) hello world

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

2. 進(jìn)行相關(guān)配置

這里網(wǎng)上很多 blog 都強(qiáng)調(diào)了要去 pom.xml 里手動(dòng)配置啟用分層打包:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <!--開(kāi)啟分層編譯支持-->
                <layers>
                    <enabled>true</enabled>
                </layers>
            </configuration>
        </plugin>
    </plugins>
</build>

2.3.x版本的時(shí)候因?yàn)槭切鹿δ苄枰謩?dòng)配置開(kāi)啟。但是目前 spring boot 版本(使用版本2.6.1)實(shí)測(cè)不需要手動(dòng)配置,默認(rèn)支持該特性。(根據(jù)一些 blog 的說(shuō)法是 2.4.x 版本之后就默認(rèn)開(kāi)啟了)

目前的官方文檔(2.6.0版本)的說(shuō)法也是默認(rèn)支持,反而不需要該特性時(shí)才需要手動(dòng)配置:

The repackaged archive includes the layers.idx file by default. To disable this feature, you can do so in the following manner:

<project>
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
               <configuration>
                   <layers>
                       <enabled>false</enabled>
                   </layers>
               </configuration>
           </plugin>
       </plugins>
   </build>
</project>

3. package

執(zhí)行 mvn package 進(jìn)行打包,得到 jar 包文件。

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

其實(shí)實(shí)際上本質(zhì)是使用了 spring-boot-maven 插件的 repackage,得到了完整的包含依賴的 jar 包和原始的 jar 包(自動(dòng)添加后綴 .original)
打開(kāi) jar 包,會(huì)發(fā)現(xiàn)在 BOOT-INF 文件夾下有 classpath.idxlayers.idx 文件,打開(kāi)看下:

classpath.idx

- "BOOT-INF/lib/logback-classic-1.2.7.jar"

- "BOOT-INF/lib/logback-core-1.2.7.jar"

- "BOOT-INF/lib/log4j-to-slf4j-2.14.1.jar"

- "BOOT-INF/lib/log4j-api-2.14.1.jar"

- "BOOT-INF/lib/jul-to-slf4j-1.7.32.jar"

- "BOOT-INF/lib/jakarta.annotation-api-1.3.5.jar"

- "BOOT-INF/lib/snakeyaml-1.29.jar"

- "BOOT-INF/lib/jackson-databind-2.13.0.jar"

- "BOOT-INF/lib/jackson-annotations-2.13.0.jar"

- "BOOT-INF/lib/jackson-core-2.13.0.jar"

- "BOOT-INF/lib/jackson-datatype-jdk8-2.13.0.jar"

- "BOOT-INF/lib/jackson-datatype-jsr310-2.13.0.jar"

- "BOOT-INF/lib/jackson-module-parameter-names-2.13.0.jar"

- "BOOT-INF/lib/tomcat-embed-core-9.0.55.jar"

- "BOOT-INF/lib/tomcat-embed-el-9.0.55.jar"

- "BOOT-INF/lib/tomcat-embed-websocket-9.0.55.jar"

- "BOOT-INF/lib/spring-web-5.3.13.jar"

- "BOOT-INF/lib/spring-beans-5.3.13.jar"

- "BOOT-INF/lib/spring-webmvc-5.3.13.jar"

- "BOOT-INF/lib/spring-aop-5.3.13.jar"

- "BOOT-INF/lib/spring-context-5.3.13.jar"

- "BOOT-INF/lib/spring-expression-5.3.13.jar"

- "BOOT-INF/lib/spring-boot-2.6.1.jar"

- "BOOT-INF/lib/spring-boot-autoconfigure-2.6.1.jar"

- "BOOT-INF/lib/slf4j-api-1.7.32.jar"

- "BOOT-INF/lib/spring-core-5.3.13.jar"

- "BOOT-INF/lib/spring-jcl-5.3.13.jar"


- "BOOT-INF/lib/spring-boot-jarmode-layertools-2.6.1.jar"

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/"

再驗(yàn)證一下:

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

分層信息 ok

4. Dockerfile

Dockerfile 文件也相對(duì)常規(guī),只是在打包鏡像之前使用 jarmode 命令把 jar 包解壓了,然后在打包鏡像過(guò)程中將不同層依次 COPY,將改動(dòng)可能性最大的應(yīng)用層放在最后,這樣前面的沒(méi)有變化就可以直接使用 Docker 的緩存以提高打包效率。

FROM eclipse-temurin:8-jre-focal 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:8-jre-focal  

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/ ./  

ENV TZ="Asia/Shanghai"  

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone  

ENV JVM_OPTS=""  

ENV JAVA_OPTS=""  

ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS org.springframework.boot.loader.JarLauncher"]

5. 應(yīng)用程序修改&dive分析

其實(shí)如果只打包一次鏡像是沒(méi)有體現(xiàn)分層的優(yōu)勢(shì)的,所以需要修改部分內(nèi)容后再打包一次(或者多次,但是本質(zhì)是一樣的所以這里只修改了一次)
修改部分應(yīng)用代碼:

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

重新打 jar 包&重新打鏡像,這樣得到了兩個(gè)鏡像:

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

使用 dive 對(duì)兩個(gè)鏡像進(jìn)行分析:

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

怎么進(jìn)行Spring?Boot?分層打包Docker?鏡像實(shí)踐及分析

可以發(fā)現(xiàn):直到發(fā)生改變的應(yīng)用層(application/application/)之前,兩邊的分層的 Id、Digest 都是完全一致的,所以這些層是可以復(fù)用的,相同的層只會(huì)在 docker 的目錄下存儲(chǔ)單個(gè),如此可以大大減少容器編譯、推送的時(shí)長(zhǎng)。

以上就是怎么進(jìn)行Spring Boot 分層打包Docker 鏡像實(shí)踐及分析,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI