溫馨提示×

溫馨提示×

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

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

如何為Spring Boot應(yīng)用程序創(chuàng)建Docker鏡像

發(fā)布時間:2021-12-13 13:53:25 來源:億速云 閱讀:226 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容主要講解“如何為Spring Boot應(yīng)用程序創(chuàng)建Docker鏡像”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何為Spring Boot應(yīng)用程序創(chuàng)建Docker鏡像”吧!

1. 傳統(tǒng)Docker構(gòu)建

使用Spring Boot 構(gòu)建 Docker 鏡像的傳統(tǒng)方法是使用 Dockerfile 。下面是一個簡單的例子:

FROM openjdk:8-jdk-alpine EXPOSE 8080 ARG JAR_FILE=target/demo-app-1.0.0.jar ADD ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]

然后我們可以使用 docker build 命令來創(chuàng)建 Docker 映像。這對大多數(shù)應(yīng)用程序都很好,但也有一些缺點。

首先,我們使用的是 Spring Boot 創(chuàng)建的 fat  jar。這會影響啟動時間,尤其是在集裝箱環(huán)境中。我們可以通過添加jar文件的分解內(nèi)容來節(jié)省啟動時間。

其次,Docker鏡像是分層構(gòu)建的。Spring Boot fat jar  的特性使得所有的應(yīng)用程序代碼和第三方庫都放在一個層中。這意味著即使只有一行代碼更改,也必須重新構(gòu)建整個層。

通過在構(gòu)建之前分解 jar  ,應(yīng)用程序代碼和第三方庫各自獲得自己的層。這樣,我們便可以利用Docker的緩存機(jī)制?,F(xiàn)在,當(dāng)某一行代碼被更改時,只需要重新構(gòu)建相應(yīng)的層。

考慮到這一點,讓我們看看Spring Boot 如何改進(jìn)創(chuàng)建Docker鏡像的過程。

2. Buildpacks

BuildPacks 是一種提供框架和應(yīng)用程序依賴性的工具。

例如,給定一個Spring Boot fat jar,一個buildpack將為我們提供Java運(yùn)行時。這使我們可以跳過 Dockerfile  并自動獲得一個合理的docker 鏡像。

Spring Boot 包括對 bulidpacks 的Maven和Gradle支持。例如,使用Maven構(gòu)建時,我們將運(yùn)行以下命令:

./mvnw spring-boot:build-image

我們觀察下一些相關(guān)的輸出,看看發(fā)生了什么:

[INFO] Building jar: target/demo-0.0.1-SNAPSHOT.jar ... [INFO] Building image 'docker.io/library/demo:0.0.1-SNAPSHOT' ... [INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 100% ... [INFO]     [creator]     ===> DETECTING [INFO]     [creator]     5 of 15 buildpacks participating [INFO]     [creator]     paketo-buildpacks/bellsoft-liberica 2.8.1 [INFO]     [creator]     paketo-buildpacks/executable-jar    1.2.8 [INFO]     [creator]     paketo-buildpacks/apache-tomcat     1.3.1 [INFO]     [creator]     paketo-buildpacks/dist-zip          1.3.6 [INFO]     [creator]     paketo-buildpacks/spring-boot       1.9.1 ... [INFO] Successfully built image 'docker.io/library/demo:0.0.1-SNAPSHOT' [INFO] Total time:  44.796 s

第一行顯示我們構(gòu)建了標(biāo)準(zhǔn)的 fat jar,與其他典型的maven包一樣。

下一行開始Docker映像構(gòu)建。然后,看到這個 bulid 拉取了 packeto 構(gòu)建器。

packeto 是基于云原生 bulidpacks 的實現(xiàn)。它負(fù)責(zé)分析我們的項目并確定所需的框架和庫。在我們的例子中,它確定我們有一個Spring  Boot項目并添加所需的構(gòu)建包。

最后,我們看到生成的Docker映像和總構(gòu)建時間。注意,在第一次構(gòu)建時,花了相當(dāng)多的時間下載構(gòu)建包并創(chuàng)建不同的層。

buildpacks 的一大特點是Docker映像是多層的。因此,如果我們只更改應(yīng)用程序代碼,后續(xù)構(gòu)建將更快:

... [INFO]     [creator]     Reusing layer 'paketo-buildpacks/executable-jar:class-path' [INFO]     [creator]     Reusing layer 'paketo-buildpacks/spring-boot:web-application-type' ... [INFO] Successfully built image 'docker.io/library/demo:0.0.1-SNAPSHOT' ... [INFO] Total time:  10.591 s

3. 層級jar包

在某些情況下,我們可能不喜歡使用 bulidpacks ——也許我們的基礎(chǔ)架構(gòu)已經(jīng)綁定到另一個工具上,或者我們已經(jīng)有了我們想要重新使用的自定義  Dockerfiles 。

基于這些原因,Spring Boot 還支持使用分層jars 構(gòu)建Docker映像。為了了解它的工作原理,讓我們看看一個典型的Spring Boot  fat jar 布局:

org/   springframework/     boot/   loader/ ... BOOT-INF/   classes/ ... lib/ ...

fat jar 由3個主要區(qū)域組成:

  • 啟動Spring應(yīng)用程序所需的引導(dǎo)類

  • 應(yīng)用程序代碼

  • 第三方庫

使用分層jar,結(jié)構(gòu)看起來很相似,但是我們得到了一個新的 layers.idx 將 fat jar 中的每個目錄映射到一個層的文件:

- "dependencies":   - "BOOT-INF/lib/" - "spring-boot-loader":   - "org/" - "snapshot-dependencies": - "application":   - "BOOT-INF/classes/"   - "BOOT-INF/classpath.idx"   - "BOOT-INF/layers.idx"   - "META-INF/"

Out-of-the-box, Spring Boot provides four layers:

開箱即用,Spring Boot 提供4層:

  • dependencies: 來自第三方的依賴

  • snapshot-dependencies: 來自第三方的 snapshot 依賴

  • resources: 靜態(tài)資源

  • application: 應(yīng)用程序代碼和資源(resources)

我們的目標(biāo)是將應(yīng)用程序代碼和第三方庫放置到層中,以反映它們更改的頻率。

例如,應(yīng)用程序代碼可能是更改最頻繁的代碼,因此它有自己的層。此外,每一層都可以獨立演化,只有當(dāng)一層發(fā)生變化時,才會為它重建 Docker 鏡像。

現(xiàn)在我們了解了分層 jar 結(jié)構(gòu),接下來看看如何利用它來制作 Docker 映像。

3.1.創(chuàng)建分層 jar

首先,我們必須建立一個項目來創(chuàng)建一個分層的jar。對于Maven,則需要在POM的 Spring Boot plugin 部分添加一個新的配置:

<plugin>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-maven-plugin</artifactId>     <configuration>         <layers>             <enabled>true</enabled>         </layers>     </configuration> </plugin>

有了這個配置,Maven package 命令(包括它的其他依賴命令)將使用前面提到的四個默認(rèn)層生成一個新的分層jar。

3.2. 查看和提取分層

下一步,我們需要從 jar 中提取層,這樣Docker鏡像才能擁有正確的層。要檢查分層jar的任何層,可以運(yùn)行以下命令:

java -Djarmode=layertools -jar demo-0.0.1.jar list

然后提取它們,運(yùn)行命令:

java -Djarmode=layertools -jar demo-0.0.1.jar extract

3.3. 創(chuàng)建Docker映像

將這些層合并到 Docker 映像中的最簡單方法是使用 Dockerfile :

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

這個 Dockerfile 從fat jar中提取層,然后將每個層復(fù)制到Docker映像中。

每個COPY指令最終都會在Docker映像中生成一個新層。

如果我們構(gòu)建這個Dockerfile,我們可以看到分層jar中的每個層都作為自己的層添加到Docker鏡像中:

... Step 6/10 : COPY --from=builder dependencies/ ./  ---> 2c631b8f9993 Step 7/10 : COPY --from=builder snapshot-dependencies/ ./  ---> 26e8ceb86b7d Step 8/10 : COPY --from=builder spring-boot-loader/ ./  ---> 6dd9eaddad7f Step 9/10 : COPY --from=builder application/ ./  ---> dc80cc00a655 ...

到此,相信大家對“如何為Spring Boot應(yīng)用程序創(chuàng)建Docker鏡像”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

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

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

AI