首頁技術文章正文

Java培訓:使用Jib插件容器化SpringBoot應用

更新時間:2022-08-11 來源:黑馬程序員 瀏覽量:

  一、序言

   近幾年,微服務已經(jīng)成為Java主流的技術方向,隨著微服務化的流行,應用容器化部署也是必不可少的。應用容器化用抽象的話來說就是:將應用程序部署到容器當中作為獨立的應用程序部署單元運行,并作為實現(xiàn)高級別資源隔離的機制。常見的容器化技術就是docker,所以簡單來說就是將微服務程序打包成鏡像,在容器中運行,但這樣做有一個關鍵問題,就是docker鏡像越大,部署的效率越低,希望通過本文為你容器化部署提供效率。

  二、 使用原始的方式構建一個docker鏡像

  我們先用原始的方式制作一個Spring boot應用程序鏡像,體會一下目前流行的容器化部署方式。

       1.創(chuàng)建spring boot應用

  我們編寫一個簡單的應用程序,只有一個hello的controller即可

  

1660184325498_1.jpg

  如果你不想創(chuàng)建該項目,[可以從這里看到源碼](https://gitee.com/jk1123/docker-jib-test/tree/master)

  打開瀏覽器簡單測試一下:

  

1660184356319_2.jpg

  2. 打包

root@ubuntu:docker-image-demo$ mvn package

  3.編寫Dockerfile

#Dockerfile 這里我們選用 jre環(huán)境 減少鏡像的體積
FROM openjdk:8-jre-alpine
#鏡像內(nèi)部創(chuàng)建一個app目錄 用來存放jar包
RUN mkdir /app
#復制jar包 到app目錄下
COPY target/docker-image-demo-0.0.1-SNAPSHOT.jar /app/app.jar
#暴露端口
EXPOSE 8080/tcp
#默認啟動程序
ENTRYPOINT java -jar /app/app.jar

  4. 創(chuàng)建鏡像

#創(chuàng)建鏡像
root@ubuntu:docker-image-demo$ docker build -t docker-image-demo:0.0.1 .

#查詢鏡像
root@ubuntu:docker-image-demo$ docker images

  

1660184499608_3.jpg

  5. 推送鏡像到registry倉庫

#將鏡像推送到鏡像倉庫 這里我們選擇阿里云的鏡像倉庫 
#登錄的步驟 請自行查閱阿里云鏡像倉庫

root@ubuntu:docker-image-demo$ docker tag docker-image-demo:0.0.1 registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test:0.0.1

#推送
root@ubuntu:docker-image-demo$ docker push registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test:0.0.1

  

1660184610101_4.jpg

  在阿里云倉庫查看鏡像

  

1660184627029_5.jpg

  三、原始方式的不足

      1.需要編寫Dockerfile

  
       鏡像的打包部署本身屬于運維工作,但是需要開發(fā)人員的介入,解放應用開發(fā)人員的雙手,不要將運維的工作引入到開發(fā)人員的工作流中。

  2. 制作鏡像耗時

  
       使用springboot的項目打包而成的jar包是一個fat jar(就是該jar中包含該應用程序需要一切依賴).導致docker鏡像制作過程當中需要復制該jar到容器中。

  稍微大一點應用程序打成fat jar 高達一兩百MB,其實最主要還是依賴的sprring全家桶的jar太多。

  3. 推送鏡像到倉庫和拉取鏡像耗時

  微服務的使用便于快速迭代服務,所以發(fā)版的頻率十分頻繁.每次推送鏡像/拉取鏡像十分耗時,因為每次發(fā)版我們的fat jar都會發(fā)生細微的改變.導致docker無法利用其緩存機制,每次都要拉取鏡像中的fat jar 那層.導致推送和拉取十分消耗網(wǎng)絡資源和時間。

  四、 使用Google jib工具

  1. 簡介

  

1660184711954_6.jpg

  Jib 是谷歌公司推出的開源 Java 鏡像構建工具,它可以將一個 Java 應用構建成 OCI 鏡像或者是 Docker 鏡像,目前最新的 Relaese 版本為 3.2.1

  JIB 具有以下特點:

  1. Jib 使用 Java 開發(fā),并作為 Maven 或 Gradle 的一部分運行.你不需要編寫 Dockerfile 或 安裝Docker 環(huán)境,甚至無需創(chuàng)建包含所有依賴的大 JAR 包,就可以構建出鏡像,并將鏡像推送到鏡像倉庫。因為 Jib 與 Java 構建過程緊密集成,所以它可以訪問到打包應用程序所需的所有信息。在后續(xù)的容器構建期間,它將自動選擇 Java 構建過的任何變體。

  2. JIB 構建出的應用鏡像,具有分層結(jié)構, 利用鏡像分層和注冊表緩存來實現(xiàn)快速、增量的構建,提高構建鏡像、推送鏡像的性能,減少鏡像存儲空間。

  3. 冪等性,Jib 支持根據(jù) Maven 和 Gradle 的構建元數(shù)據(jù)進行聲明式的[容器鏡像](https://cloud.tencent.com/product/tcr?from=10680)構建,只要輸入保持不變,就可以通過配置重復創(chuàng)建相同的鏡像。

  下圖是官方給出的性能測試

  

1660184766802_7.jpg

  

1660184780438_8.jpg

  2.使用

  如此強大的工具使用起來相當?shù)暮唵?br/>

  2.1 導入插件依賴

<!-- pom文件中添加jib的插件-->
<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>3.2.0</version>
</plugin>

  2.2 配置插件

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <from>
            <!--基礎鏡像名字-->
            <image>openjdk:8-jre-alpine</image>
        </from>
        <to>
            <image>registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test</image>
            <tags>
                <tag>0.0.2</tag>
            </tags>
            <!--<auth>-->
            <!--<username>自己倉庫的賬號</username>-->
            <!--<password>寫自己的倉庫密碼</password>-->
            <!--</auth>-->
            <!--
             其實這里還是建議 使用maven-setting的配置方式 請參照
             https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#authentication-methods
             https://maven.apache.org/guides/mini/guide-encryption.html
            -->
        </to>
        <container>
            <!--指明主類-->
            <mainClass>com.jk1123.docker.DockerImageDemoApplication</mainClass>
            <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
            <jvmFlags>
                <jvmFlag>-Dmy.property=example.value</jvmFlag>
                <jvmFlag>-Xms512m</jvmFlag>
                <jvmFlag>-Xmx2048m</jvmFlag>
            </jvmFlags>
            <ports>
                <port>8080</port>
            </ports>
            <labels>
                <org.label-schema.schema-version>1.0</org.label-schema.schema-version>
                <org.label-schema.name>docker-image-test</org.label-schema.name>
                <org.label-schema.vendor>jk1123</org.label-schema.vendor>
                <org.label-schema.license>GPLv2</org.label-schema.license>
                <org.label-schema.build-date>${maven.build.timestamp}</org.label-schema.build-date>
                <org.opencontainers.image.title>docker-image-test Image</org.opencontainers.image.title>
                <org.opencontainers.image.vendor>jk1123</org.opencontainers.image.vendor>
                <org.opencontainers.image.licenses>GPL-2.0-only</org.opencontainers.image.licenses>
                <org.opencontainers.image.created>${maven.build.timestamp}</org.opencontainers.image.created>
            </labels>
        </container>
        <allowInsecureRegistries>true</allowInsecureRegistries>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <!-- 本地構建這個-->
                <!--<goal>dockerBuild</goal>-->
                <!-- 遠程構建是這個-->
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
</plugin>

  2.3.執(zhí)行構建

root@ubuntu:docker-image-demo$ mvn package jib:build

  

1660184928080_9.jpg

  五、 JIB原理分析

  1. docker鏡像緩存

  docker的鏡像是由一層層構成的

  我們?nèi)绻捎迷挤绞酱虬R像,鏡像分層如圖.在這種情況下,如果我們的代碼有變化,就會重新制作一個springboot的fat jar,這個jar中即時只有一行代碼改變了,生成的新的jar也與原來的文件也變化,docker制作鏡像的時候 該層發(fā)生了變化就需要重新制作,而一個fat jar非常的大,無法利用鏡像的緩存功能。

  2. jib構建鏡像分層

  Jib 在編譯 springboot應用的時候考慮到的docker鏡像的緩存功能,能利用緩存盡量的利用鏡像的緩存。

  通過分析我們會發(fā)現(xiàn)如下規(guī)律:

  1.應用代碼是最容易發(fā)生變化的,但是代碼文件實際占用并不是太高(相對于引入jar包大小而言)

  2.應用的配置文件也容易發(fā)生變化,但是變化頻率相對于代碼要低一些

  3.應用依賴的其他的公共子模塊也容易發(fā)生變化,但是變化頻率相對于代碼要更低一些

  4.應用依賴的一些快照jar包也容易發(fā)生變化,頻率更低

  5.應用依賴的常規(guī)jar,例如spring系列的jar包,變化頻率不大,試想誰會天天換spring版本號呢

  綜上所述,jib的作者充分考慮到這些規(guī)律,將鏡像分成好幾層,充分利用的docker鏡像緩存機制和資源的變化頻率的特性,接下來我們來看看使用jib制作的鏡像的層級關系圖

  首先我們先看看我們的項目結(jié)構

  

1660185036673_11.jpg

  接下來我們來看看鏡像的層級結(jié)構圖

  

  可見jib充分考慮和利用的docker鏡像緩存的機制,來幫我們制作鏡像.這樣當我們的應用重新發(fā)版的時候,可以減少鏡像的push和pull的速度。

  注:

  上圖分析工具使用dive工具

  關于dive工具的使用請參照這里:

  github:https://github.com/wagoodman/dive

  gitee:https://gitee.com/mirrors/Dive

  六、 結(jié)束語

  通過如上的分析,相信大家對jib插件有個清晰的認知:

  jib就是根據(jù)應用的不同資源的變化頻率和docker鏡像的緩存機制,充分利用docker鏡像的分層機制.提高鏡像的制作和發(fā)布性能.

  最后,希望各位讀者早日用上jib來打包您的應用,減少鏡像的體積,減少打包消耗,減少傳輸消耗,暢享綠色生活!!!

分享到:
在線咨詢 我要報名
和我們在線交談!