Spring?Boot?分層打包?Docker?鏡像實(shí)踐及分析(推薦)
1. 準(zhǔn)備 spring boot 項(xiàng)目
簡(jiǎn)單,略過(guò)
spring boot 版本 > 2.3.x 即可
簡(jiǎn)單寫了一個(gè) hello world
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> <!--開啟分層編譯支持--> <layers> <enabled>true</enabled> </layers> </configuration> </plugin> </plugins> </build>
2.3.x版本的時(shí)候因?yàn)槭切鹿δ苄枰謩?dòng)配置開啟。但是目前 spring boot 版本(使用版本2.6.1)實(shí)測(cè)不需要手動(dòng)配置,默認(rèn)支持該特性。(根據(jù)一些 blog 的說(shuō)法是 2.4.x 版本之后就默認(rèn)開啟了)
目前的官方文檔(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 包文件。
其實(shí)實(shí)際上本質(zhì)是使用了 spring-boot-maven 插件的 repackage,得到了完整的包含依賴的 jar 包和原始的 jar 包(自動(dòng)添加后綴 .original)
打開 jar 包,會(huì)發(fā)現(xiàn)在 BOOT-INF 文件夾下有 classpath.idx
和 layers.idx
文件,打開看下:
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)證一下:
分層信息 ok
4. Dockerfile
Dockerfile 文件也相對(duì)常規(guī),只是在打包鏡像之前使用 jarmode 命令把 jar 包解壓了,然后在打包鏡像過(guò)程中將不同層依次 COPY,將改動(dòng)可能性最大的應(yīng)用層放在最后,這樣前面的沒有變化就可以直接使用 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í)如果只打包一次鏡像是沒有體現(xiàn)分層的優(yōu)勢(shì)的,所以需要修改部分內(nèi)容后再打包一次(或者多次,但是本質(zhì)是一樣的所以這里只修改了一次)
修改部分應(yīng)用代碼:
重新打 jar 包&重新打鏡像,這樣得到了兩個(gè)鏡像:
使用 dive 對(duì)兩個(gè)鏡像進(jìn)行分析:
可以發(fā)現(xiàn):直到發(fā)生改變的應(yīng)用層(application/application/)之前,兩邊的分層的 Id、Digest 都是完全一致的,所以這些層是可以復(fù)用的,相同的層只會(huì)在 docker 的目錄下存儲(chǔ)單個(gè),如此可以大大減少容器編譯、推送的時(shí)長(zhǎng)。
(具體 docker 鏡像的分層的了解還有限,后續(xù)再進(jìn)一步了解)
到此這篇關(guān)于Spring Boot 分層打包 Docker 鏡像實(shí)踐及分析的文章就介紹到這了,更多相關(guān)Spring Boot 分層打包 Docker 鏡像內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
清理docker磁盤空間的方法總結(jié)(附詳細(xì)講解)
docker?鏡像特別容易占空間,稍微不注意可能磁盤爆滿,所以本文給大家詳細(xì)介紹了如何清理?docker?磁盤空間,并通過(guò)代碼示例給大家講解的非常詳細(xì),需要的朋友可以參考下2024-02-02Docker搭建Redis5.0并掛載數(shù)據(jù)
本文主要介紹了Docker搭建Redis5.0并掛載數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07Mac系統(tǒng)上用Docker搭建lamp環(huán)境
這篇文章主要給大家介紹了Mac系統(tǒng)上用Docker如何搭建lamp環(huán)境,文章給大家介紹的很詳細(xì),有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-12-12Docker在Windows環(huán)境的搭建和使用詳解
這篇文章主要介紹了Docker在Windows環(huán)境的搭建和使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03