無需Docker File,用三種方式創(chuàng)建Spring Boot應(yīng)用的Docker鏡像
引言
隨著技術(shù)的發(fā)展,應(yīng)用程序的部署方式也在不斷演變。傳統(tǒng)的部署方式需要為每個應(yīng)用程序提供一臺獨立的機器,并確保機器的配置滿足應(yīng)用程序的運行需求。
然而,引入了容器的概念后,開發(fā)者在面對這個問題時有了更好的解決方案。容器將整個軟件堆棧打包成一個獨立的實體,并可以方便地進行部署,不再受限于"在我的機器上可以運行"的問題。
因此,今天我們介紹三種構(gòu)建Spring Boot應(yīng)用程序的Docker鏡像的機制:Spring Boot構(gòu)建插件;Fabric8 Maven插件;JIB Maven插件。
創(chuàng)建應(yīng)用程序
訪問https://start.spring.io,并創(chuàng)建一個僅包含spring-web依賴項的應(yīng)用程序。
添加一個簡單的控制器來接受一些請求。
@RestController
@SpringBootApplication
public class ServiceDockerImageBuildApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceDockerImageBuildApplication.class, args);
}
@GetMapping("/")
public ResponseEntity get(){
return ResponseEntity.ok("All Ok");
}
}
當(dāng)運行這個應(yīng)用程序并打開"http://localhost:8080"時,會得到一個響應(yīng)"All Ok"。
接下來,使用Spring Boot構(gòu)建插件構(gòu)建我們的Docker鏡像。
1 使用Spring Boot構(gòu)建插件構(gòu)建Docker鏡像
Spring Boot的構(gòu)建插件提供了一種使用BuildPacks概念創(chuàng)建Docker鏡像的方法。Build Packs提供了一種定義應(yīng)用程序構(gòu)建方式的方法。它會檢測應(yīng)用程序的類型并進行構(gòu)建,以便在特定平臺上或獨立于平臺運行。
現(xiàn)在,Spring Boot的構(gòu)建插件使用BuildPack構(gòu)建器鏡像,會自動檢測到它是一個Spring Boot應(yīng)用程序,并構(gòu)建相關(guān)的鏡像。
只需要使用Maven在Spring Boot應(yīng)用程序上調(diào)用image-build目標(biāo)即可。
mvn spring-boot:build-image
這將從BuildPacks中拉取基礎(chǔ)構(gòu)建器鏡像,以檢測應(yīng)用程序的類型并選擇適用于該應(yīng)用程序的構(gòu)建包。然后,它使用所選的構(gòu)建包構(gòu)建您的最終鏡像。
這里是一個顯示構(gòu)建包所需的構(gòu)建過程的日志。
===> DETECTING
[INFO] [creator] 6 of 24 buildpacks participating
[INFO] [creator] paketo-buildpacks/ca-certificates 3.2.4
[INFO] [creator] paketo-buildpacks/bellsoft-liberica 9.3.7
[INFO] [creator] paketo-buildpacks/syft 1.12.0
[INFO] [creator] paketo-buildpacks/executable-jar 6.2.4
[INFO] [creator] paketo-buildpacks/dist-zip 5.2.4
[INFO] [creator] paketo-buildpacks/spring-boot 5.12.0
...
...
[INFO] Successfully built image 'docker.io/library/service-docker-image-build:0.0.1-SNAPSHOT'
可以使用參數(shù)指定最終鏡像的名稱,如下所示:
mvn spring-boot:build-image \
-Dspring-boot.build-image.imageName=my-spring-boot-image
或者可以在配置中指定,如下所示:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<imageName>my-spring-boot-image</imageName>
</configuration>
</plugin>
現(xiàn)在,可以在這里進行一些級別的自定義。如果想真正自定義鏡像的構(gòu)建過程,需要創(chuàng)建自己的構(gòu)建器鏡像來定義構(gòu)建過程。
2 使用Fabric8 Maven插件構(gòu)建Docker鏡像
Fabric8 Maven插件為構(gòu)建和部署Java應(yīng)用程序提供了一種簡化的方法,包括創(chuàng)建Docker鏡像。
首先,需要在pom.xml文件中添加Fabric8 Maven插件的依賴項。
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.37.0</version>
<executions>
<execution>
<id>docker-build</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<images>
<image>
<name>my-spring-boot-image</name>
<build>
<from>openjdk:11-jdk-slim</from>
<tags>
<tag>latest</tag>
</tags>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
</build>
</image>
</images>
</configuration>
</plugin>
配置部分非常簡單。讓我們看一下<build>部分中的一些重要部分。
在<from>標(biāo)簽中,指定了基礎(chǔ)鏡像,然后在<assembly>部分指定了鏡像的組裝方式。
在assembly部分,使用值為artifact的<descriptorRef>來指定我們只想復(fù)制構(gòu)建的artifact,并使用<name>標(biāo)簽指定它將被復(fù)制到目標(biāo)鏡像中的位置。由于這里構(gòu)建了一個單獨的fat jar,只需復(fù)制artifact。
最后,指定<cmd>來運行被復(fù)制的jar文件。
運行maven構(gòu)建命令后,鏡像將被構(gòu)建。
檢查鏡像的層,發(fā)現(xiàn)artifact被復(fù)制為最后一層,如下所示。
圖片
可以創(chuàng)建分層的Docker鏡像,通過在assembly標(biāo)簽中指定要創(chuàng)建的層以及需要在這些層中復(fù)制的內(nèi)容。
現(xiàn)在,可以使用docker run -p 8080:8080 service-docker-image-build:0.0.1-SNAPSHOT簡單地運行docker文件。
3 使用Google的JIB插件構(gòu)建Docker鏡像
讓我們來看看來自Google的JIB插件。它是由Google提供和維護的工具之一,提供了相當(dāng)詳細的自定義級別。
<build>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<from>
<image>openjdk:17</image>
</from>
<to>
<image>jib-build-${project.name}:${project.version}</image>
</to>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>dockerBuild</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
這里,在<from>標(biāo)簽中指定了所需的基礎(chǔ)鏡像,而在<to>標(biāo)簽中指定了最終鏡像的名稱。
現(xiàn)在,在<execution>部分中使用了dockerBuild目標(biāo),這樣Docker鏡像將會構(gòu)建到本地Docker守護程序中。如果使用build目標(biāo),JIB插件將會構(gòu)建Docker鏡像并將其推送到相應(yīng)的倉庫。它支持所有主要的倉庫,如docker.io、AWS ECR、Google GCR、Azure ACR等。為此,可以設(shè)置身份驗證機制以推送鏡像。
來看看創(chuàng)建的鏡像的層次結(jié)構(gòu)。
圖片
圖像的層次結(jié)構(gòu)如下所示:
- 第 1 層:包含所有依賴項。
- 第 2 層:包含應(yīng)用程序資源。
- 第 3 層:包含應(yīng)用程序類。
- 第 4 層:包含jib-classpath-file,其中包含類路徑信息,以及jib-main-class-file,其中包含要執(zhí)行的完全限定的主類的名稱。