<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 Google Jib 構(gòu)建 Java 容器

          共 5114字,需瀏覽 11分鐘

           ·

          2021-02-03 06:31

          隨著近些年的技術(shù)發(fā)展,Java 領(lǐng)域微服務(wù)已經(jīng)成為主流的技術(shù)方向。隨著微服務(wù)化,云原生的概念也逐漸火熱起來,不了解云原生仿佛就是一個(gè)原始人。而在云原生中,應(yīng)用容器化 是其核心屬性之一。

          應(yīng)用容器化,用抽象的話來說就是:將軟件容器中的應(yīng)用程序和進(jìn)程作為獨(dú)立的應(yīng)用程序部署單元運(yùn)行,并作為實(shí)現(xiàn)高級別資源隔離的機(jī)制。從總體上改進(jìn)開發(fā)者的體驗(yàn)、促進(jìn)代碼和組件重用,而且要為云原生應(yīng)用簡化運(yùn)維工作。通俗點(diǎn)說,就是借助于 Docker 等容器化技術(shù),將一個(gè)個(gè)的微服務(wù)打包成鏡像,在容器中獨(dú)立部署運(yùn)行。

          背景

          我司目前采用的是基于 GitLab + Jenkins + Rancher 這套 CI/CD 體系。在這套體系中微服務(wù)的容器化依賴于 Jenkins 去實(shí)現(xiàn)。現(xiàn)在假設(shè)我們有一個(gè)項(xiàng)目,其組織結(jié)構(gòu)如下:

          parentPro
          ????|--?moduleA
          ????|--?moduleB
          ????|--?rest????[rest?模塊為?spring?boot?啟動入口,并依賴?moduleA、moduleB]

          對于 SpringBoot 項(xiàng)目,Maven 的默認(rèn)構(gòu)建工具是 Spring-boot-maven-plugin,構(gòu)建出產(chǎn)物為 Fat JarFat jar 中包含有 rest 模塊中的 classes,及 rest 所依賴的 moduleAmoduleB 及其他第三方 jar 庫。最終,通過 Jenkins 的 Dockerfile 文件將 Fat jar 基于 JDK 基礎(chǔ)鏡像層構(gòu)建,產(chǎn)生一個(gè)新的應(yīng)用鏡像。

          每次應(yīng)用構(gòu)建新版本鏡像時(shí),因?yàn)?Maven 構(gòu)建產(chǎn)出物是 Fat jar,當(dāng) restmoduleAmoduleB 模塊中任意一處發(fā)生變化時(shí),都會產(chǎn)出一個(gè)新的 Fat jar。構(gòu)建鏡像時(shí)都要將整個(gè) Fat jar 重新寫入到鏡像層,并將整個(gè)鏡像層推送到鏡像倉庫中,大大降低了鏡像構(gòu)建和推送的性能,并導(dǎo)致同一個(gè)應(yīng)用鏡像的多個(gè) Tag 占用大量的存儲空間。

          Google Jib

          介紹

          Jib 是谷歌公司推出的開源 Java 鏡像構(gòu)建工具,它可以將一個(gè) Java 應(yīng)用構(gòu)建成 OCI 鏡像或者是 Docker 鏡像,目前最新的 Relaese 版本為 1.8.0。

          JIB 具有以下特點(diǎn):

          1. Jib 使用 Java 開發(fā),并作為 Maven 或 Gradle 的一部分運(yùn)行。你不需要編寫 Dockerfile 或 Docker 環(huán)境,甚至無需創(chuàng)建包含所有依賴的大 JAR 包,就可以構(gòu)建出鏡像,并將鏡像推送到鏡像倉庫。因?yàn)?Jib 與 Java 構(gòu)建過程緊密集成,所以它可以訪問到打包應(yīng)用程序所需的所有信息。在后續(xù)的容器構(gòu)建期間,它將自動選擇 Java 構(gòu)建過的任何變體。
          2. JIB 構(gòu)建出的應(yīng)用鏡像,具有分層結(jié)構(gòu), 利用鏡像分層和注冊表緩存來實(shí)現(xiàn)快速、增量的構(gòu)建,提高構(gòu)建鏡像、推送鏡像的性能,減少鏡像存儲空間。
          3. 冪等性,Jib 支持根據(jù) Maven 和 Gradle 的構(gòu)建元數(shù)據(jù)進(jìn)行聲明式的容器鏡像構(gòu)建,只要輸入保持不變,就可以通過配置重復(fù)創(chuàng)建相同的鏡像。

          下圖為某微服務(wù)開啟 Jib 構(gòu)建后在 Jenkins 中的構(gòu)建過程,可以看出構(gòu)建速度的提升主要在 package 和 push 階段。

          原理

          Jib 在編譯 Java 應(yīng)用時(shí),會將 Java 項(xiàng)目內(nèi)的資源及所依賴的資源,基于變化頻率不同分成多個(gè)部分,并將每個(gè)部分都單獨(dú)作為一個(gè)鏡像層存在,這樣其中一部分資源發(fā)生變化時(shí),只需要重新構(gòu)建該部分所屬鏡像層即可。以第二節(jié)的應(yīng)用為例,rest 應(yīng)用鏡像將被分為以下鏡像層:

          • Classes: rest 模塊中的 class 信息,這部分信息變化頻率最高,處于最上層鏡像層;
          • Resources: rest 模塊中的配置文件,這部分信息變化頻率較低,處于第二層鏡像層;
          • Project Dependencies: rest 模塊的項(xiàng)目依賴信息,在當(dāng)前示例中為 moduleAmoduleB,這部分內(nèi)容比依賴第三方 Jar 庫更容易變化,所以也單獨(dú)做為一個(gè)鏡像層存在;
          • Snapshot Dependencies:rest 模塊所依賴的 SnapShot Jar 庫
          • All other Dependencies: rest 模塊所依賴的其他類型 Jar 庫;
          • Each extra directory:其他所依賴額外資源目錄;

          基于 Jib 插件構(gòu)建出的鏡像,與使用以下 Dockerfile 所構(gòu)建出的鏡像相同:

          簡單上手

          源碼地址:https://github.com/jitwxs/blog_sample

          基礎(chǔ)配置

          創(chuàng)建一個(gè)全新的 SpringBoot 項(xiàng)目,依賴只包含 spring-boot-starter-web 這一個(gè)即可。編寫一個(gè) Controller 類,用于測試:

          @RestController
          public?class?DemoController?{
          ????@GetMapping("/hello")
          ????public?String?hello()?{
          ????????return?"hello?world!";
          ????}
          }

          然后,在 POM 文件中添加 JIB 插件:

          <plugin>
          ??<groupId>com.google.cloud.toolsgroupId>
          ??<artifactId>jib-maven-pluginartifactId>
          ??<version>1.8.0version>
          ??<configuration>
          ????<from>
          ??????<image>harbor.jitwxs-inc.com/base/java:8-jdk-alpineimage>
          ????from>
          ????<to>
          ??????<image>harbor.jitwxs-inc.com/sample/${artifactId}:v1image>
          ????to>
          ????<allowInsecureRegistries>trueallowInsecureRegistries>
          ??configuration>
          plugin>

          介紹一下含義:

          • 基礎(chǔ)鏡像信息,即構(gòu)建本鏡像所基于的根鏡像
          • 輸出鏡像信息, 表示本鏡像構(gòu)建完成后,要發(fā)布到哪里去
          • 允許使用 HTTP 協(xié)議連接 Registry 倉庫
          • 鏡像名,命名格式為:Registry 倉庫地址/屬組/鏡像名:Tag名

          由于 Docker Hub 的速度實(shí)在是太感人了,開著梯子都 push 不上去,因此我使用了私服倉庫。如果使用 Docker Hub,那么 image 標(biāo)簽內(nèi)容形如:docker.io/jitwxs/image_name:tag,其中 jitwxs 為你的 DockerHub 唯一ID,一般是用戶名。

          配置完畢后,使用如下命令編譯,并自動 push 到倉庫中:

          mvn clean package -DskipTests jib:build

          核心就是 jib:build,更多命令見文檔:https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#build-your-image

          鑒權(quán)

          運(yùn)行后,發(fā)現(xiàn)拋了如下的錯誤。根據(jù)錯誤日志可知連接 Registry 倉庫時(shí)需要鑒權(quán)。

          命令行

          第一種方式也是最粗暴的,在執(zhí)行 maven 命令時(shí)傳遞 Registry 倉庫的用戶名密碼。

          mvn clean package -DskipTests jib:build \
          -Djib.from.auth.username=admin \
          -Djib.from.auth.password=admin \
          -Djib.to.auth.username=admin \
          -Djib.to.auth.password=admin

          由于 中的鏡像可能不是來自于同一個(gè) Registry 倉庫,因此既要配置 from 的用戶名密碼,也要配置 to 的用戶名密碼。

          執(zhí)行完畢后,通過命令行,或者可視化工具,查看是否被 push 上去(此處我使用的工具是 Harbor)。

          配置文件

          使用命令行方式每次執(zhí)行都要輸入那么長一串命令,這樣實(shí)在是不方便。另一種方法是在 pom.xml 文件直接將用戶名密碼配置進(jìn)去,形如:

          <plugin>
          ??<groupId>com.google.cloud.toolsgroupId>
          ??<artifactId>jib-maven-pluginartifactId>
          ??<version>1.8.0version>
          ??<configuration>
          ????<from>
          ??????<image>harbor.jitwxs-inc.com/base/java:8-jdk-alpineimage>
          ??????<auth>
          ????????<username>my_usernameusername>
          ????????<password>my_passwordpassword>
          ??????auth>
          ????from>
          ????<to>
          ??????<image>harbor.jitwxs-inc.com/sample/${artifactId}:v1image>
          ??????<auth>
          ????????<username>my_usernameusername>
          ????????<password>my_passwordpassword>
          ??????auth>
          ????to>
          ????<allowInsecureRegistries>trueallowInsecureRegistries>
          ??configuration>
          plugin>

          即給 from 和 to 標(biāo)簽都加上 標(biāo)簽,但是這種方式實(shí)在是不夠優(yōu)雅,因?yàn)閷⒂脩裘艽a硬編碼在代碼中會帶來安全性問題。

          合適的方法是配置在 Maven 的 settings.xml 配置文件中,在 標(biāo)簽中,新增一個(gè) 節(jié)點(diǎn),配置 Registry 倉庫的用戶名密碼。

          <servers>
          ????...
          ????<server>
          ??????<id>harbor.jitwxs-inc.comid>
          ??????<username>adminusername>
          ??????<password>adminpassword>
          ??????<configuration>
          ????????<email>[email protected]email>
          ??????configuration>
          ????server>
          servers>

          配置完畢后,讓我們把項(xiàng)目的 tag 從 v1 修改為 v2,再執(zhí)行次命令驗(yàn)證下:

          mvn clean package -DskipTests jib:build

          可以看到正常被 push 上去了。最后官方文檔詳細(xì)介紹了各種鑒權(quán)方式的使用,參見:https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#authentication-methods

          本地構(gòu)建

          下面試下在本地進(jìn)行構(gòu)建,首先使用 docker 命令將鏡像拉取下來:

          > ~: docker pull harbor.jitwxs-inc.com/sample/springboot_jib:v2
          v2: Pulling from sample/springboot_jib
          53478ce18e19: Pull complete
          d1c225ed7c34: Pull complete
          887f300163b6: Pull complete
          471ae92a2408: Pull complete
          286e54d31846: Pull complete
          4f4af7a6fe32: Pull complete
          Digest: sha256:dfb6628201b1c5fec5eaca00deec157d437559356043043e636fe11b6f3ce1fe
          Status: Downloaded newer image for harbor.jitwxs-inc.com/sample/springboot_jib:v2

          然后基于該鏡像,創(chuàng)建容器,并后臺運(yùn)行在 8080 端口:

          docker run -d --name jib_test -p 8080:8080 harbor.jitwxs-inc.com/sample/springboot_jib:v2

          打開瀏覽器,請求接口 http://127.0.0.1:8080/hello,正確輸出。

          綁定到生命周期

          如果你不想單獨(dú)輸入 jib:build,你可以把 jib 綁定到 Maven 命令中,在插件中添加如下的 標(biāo)簽即可。

          <plugin>
          ??<groupId>com.google.cloud.toolsgroupId>
          ??<artifactId>jib-maven-pluginartifactId>
          ??...
          ??<executions>
          ????<execution>
          ??????<phase>packagephase>
          ??????<goals>
          ????????<goal>buildgoal>
          ??????goals>
          ????execution>
          ??executions>
          plugin>

          然后通過 Maven 的 mvn package 命令就會自動構(gòu)建鏡像了。

          驗(yàn)證

          這里推薦一個(gè)工具 dive, dive 能夠通過文件目錄的形式直觀地顯示一個(gè)鏡像中的每個(gè)鏡像層內(nèi)的內(nèi)容,便于查看鏡像的分層信息。

          ./dive harbor.okcoin-inc.com/sample/springboot_jib:v1

          原文鏈接:https://blog.csdn.net/yuanlaijike/article/details/103606999


          CKA 認(rèn)證培訓(xùn)


          ?點(diǎn)擊屏末?|??|?即刻學(xué)習(xí)

          瀏覽 34
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩精品A片一区二区三区+卡 | 我要看操逼的片子能给我播放吗谢谢 | 人人尻人人摸 | 亚洲色老板 | 日韩久久免费观看 |