Docker化Spring Boot應用程序的兩種方法

微服務通常使用Spring Boot框架構建,並與Docker一起部署。本文探討了用於Docker化Spring Boot應用程序的兩個常見選項。在整個過程中,我們將使用一個簡單的REST應用程序作為運行示例。

本文使用Spring Tool Suite來構建應用程序,雖然只要有pom文件,IDE和應用程序都不會那麼重要。在本文中還是要假定讀者對Docker的瞭解最少,我們將討論的選擇之一不需要Docker。然後是REST控制器:

<code>

package

hello;

import

org.springframework.boot.SpringApplication;

import

org.springframework.boot.autoconfigure.SpringBootApplication;

import

org.springframework.web.bind.

annotation

.RequestMapping;

import

org.springframework.web.bind.

annotation

.RestController;

public

class

Application

{

public

String home() {

return

"Hello from Spring Boot in Docker"

; }

public

static void main(String[] args) { SpringApplication.run(Application

.

class

,

args);

} }/<code>

package hello;我們將其構建到目標目錄中的fat jar中。Dockerize的最簡單方法是將fat jar填充到容器中:

Docker文件

<code>

FROM

adoptopenjdk:

11

-jre-hotspot ARG JAR_FILE=target/

*.jar

COPY

${JAR_FILE}

app.jar ENTRYPOINT [

"java"

,

"-jar"

,

"/app.jar"

/<code>

事實證明這不是個好方法。

在這種情況下,我們的應用程序及其所有依賴項都放在了一層。如果我們不斷更改應用程序,那麼即使依賴項jar很少更改,每次也會從頭開始重建映像。這就導致了構建很緩慢。

更好的選擇是遵循舊的軟件設計原則,並從保持不變的地方區分出一些變化。我們可以通過將依賴項放在底層,將應用程序放在頂層來做到這一點。Docker隨後將緩存依賴關係層,並且每次我們更改應用程序並重建映像時,將從緩存中檢索依賴關係層,從而加快構建速度。

對於第一個選擇,我們考慮一個非常傳統的團隊,其中開發團隊和構建團隊是分開的;開發人員對Docker一無所知,也不想知道。開發團隊將構建應用程序,並將其交給構建團隊來管理構建和部署。


Docker化Spring Boot應用程序的兩種方法

fat jar分為三個部分:

  • 用於引導jar加載的類
  • 在BOOT-INF / classes中的應用程序類
  • BOOT-INF / lib中的依賴項

可以通過檢查jar文件(jar tvf app.jar)來查看。我們可以利用這一點來分離各層。當然可以提取jar文件,然後在Dockerfile中移動並複製圖層。但Spring使分層罐變得更加容易。因此,開發人員調整pom文件以啟用圖層

<code>

<

plugins

>

<

plugin

>

….

<

configuration

>

<

layers

>

<

enabled

>

true

enabled

>

layers

>

configuration

>

plugin

>

plugins

>

/<code>

開發團隊將自己構建的fat jar移交給構建團隊。

列出圖層

<code>java -Djarmode=layertools -jar app.jar 

list

dependencies spring-boot-loader snapshot-dependencies application/<code>

現在,構建團隊可以提取jar文件的層並將其複製到多級docker文件中的映像層(多級docker文件是具有許多已命名構建階段的文件)

Docker文件

<code>

FROM

adoptopenjdk:11-jre-hotspot as builder

WORKDIR

application

ARG

JAR_FILE=target/*.jar

COPY

${JAR_FILE} application.jar

RUN

java -Djarmode=layertools -jar application.jar extract

FROM

adoptopenjdk:11-jre-hotspot

WORKDIR

application

COPY

application/dependencies/ ./

COPY

application/spring-boot-loader/ ./

COPY

application/snapshot-dependencies/ ./

COPY

application/application/ ./

ENTRYPOINT

["java", "org.springframework.boot.loader.JarLauncher"]

/<code>

請注意,Dockerfile中沒有特定於應用程序的內容,這就是我們使用jarlauncher的原因。它將使圖像開始變慢,不過影響不大。此外,我們假設存在Docker的本地實例

我們可以照常構建圖像(將圖像稱為“示例”)

docker構建 標籤示例

<code>

docker

images

REPOSITORY

TAG IMAGE ID CREATED SIZE

example

latest de7a3bb4889e 7 days ago 243MB

/<code>

現在運行它:

docker run -it -p80:8080 example:latest

並在瀏覽器中轉到localhost,然後看到“在Docker中從Spring Boot向您問好”。

第二種選擇是根據微服務原則建立更現代化的團隊。在這裡,開發團隊本身負責構建和部署Docker映像。但是開發團隊仍然對Docker一無所知。

此外先了解一下jib。

“ Jib是一個快速,簡單的容器映像生成器,它處理將應用程序打包為容器映像的所有步驟。它不需要編寫Dockerfile或安裝Docker,它可以直接集成到 Maven 和 Gradle中-只需將插件添加到構建中,就可以立即將Java應用程序容器化”

Docker化Spring Boot應用程序的兩種方法

要使用Jib,我們修改pom以插入:

<code>

<

plugin

>

<

groupId

>

com.google.cloud.tools

groupId

>

<

artifactId

>

jib-maven-plugin

artifactId

>

<

version

>

2.4.0

version

>

<

configuration

>

<

to

>

<

image

>

jibexample2

image

>

to

>

configuration

>

plugin

>

/<code>

現在,對於此示例,我們假設團隊有一個正在運行 的Docker本地實例,

我們已將圖像命名為jibexample2。現在建立專案

mvn compile jib:dockerBuild

如果列出docker映像(docker映像),將會看到:

“存儲庫標記圖像ID的創建大小”

jibexample2 latest 7b84d5781eca 50 years ago 142MB

沒有Docker文件,也沒有Docker知識。注意大小。可以通過docker inspect檢查映像,並查看入口點是hello。應用程序,都可以看到列出的圖層。這些層有些不同:

    • Classes
    • Resources
    • Project dependencies
    • Snapshot dependencies
    • All other dependencies

基本映像是Distroless Java。非發行版映像僅包含運行時依賴項。它們不包含程序包管理器,shell或期望在標準Linux發行版中找到的任何其他程序。每個人都可以更改基本圖像。Jib計算出ENTRYPOINT。為了進行比較,這裡是Jib隱式使用的Dockerfile。

<code>

1

2

3

FROM

gcr.io/distroless/java:latest

4

5

6

7

COPY

dependencyJars

/app/libs

8

9

COPY

snapshotDependencyJars

/app/libs

10

11

COPY

projectDependencyJars

/app/libs

12

13

COPY

resources

/app/resources

14

15

COPY

classFiles

/app/classes

16

17

18

19

20

21

ENTRYPOINT

["java",

jib.container.jvmFlags,

"-cp"

,

"/app/resources:/app/classes:/app/libs/*"

,

jib.container.mainClass]

CMD

[jib.container.args]

/<code>

另外,我們可以使用jib:build代替jib:dockerBuild,如果提供了憑據,它將把映像推送到遠程註冊表。使用jib:buildTar可以將映像另存為tarball到target / jib-image.tar,你可以對其進行檢查並將其導入Docker。Jib還有許多其他配置。


分享到:


相關文章: