Kuunda Picha za Docker Iliyoboreshwa kwa Maombi ya Boot ya Spring

Vyombo vimekuwa njia inayopendekezwa ya kufunga programu na utegemezi wake wote wa programu na mfumo wa uendeshaji na kisha kuziwasilisha kwa mazingira tofauti.

Nakala hii inashughulikia njia tofauti za kuweka programu ya Boot ya Spring:

  • kuunda picha ya Docker kwa kutumia faili ya Docker,
  • kuunda picha ya OCI kutoka kwa chanzo kwa kutumia Cloud-Native Buildpack,
  • na uboreshaji wa picha wa wakati unaotumika kwa kutenganisha sehemu za JAR katika tabaka tofauti kwa kutumia zana za viwango vingi.

 Mfano wa kanuni

Nakala hii inaambatana na mfano wa nambari ya kufanya kazi kwenye GitHub .

Istilahi ya kontena

Tutaanza na istilahi ya kontena iliyotumiwa katika makala:

  • Picha ya chombo: faili ya umbizo maalum. Tutabadilisha programu yetu kuwa picha ya chombo kwa kuendesha zana ya ujenzi.
  • chombo: Mfano unaoweza kutekelezwa wa picha ya chombo.
  • Injini ya chombo: Mchakato wa daemoni unaohusika na kuendesha kontena.
  • Mpangishi wa kontena: Kompyuta mwenyeji ambayo injini ya kontena huendesha.
  • Usajili wa chombo: Eneo la jumla linalotumika kuchapisha na kusambaza picha ya kontena.
  • Kiwango cha OCIFungua Mpango wa Kontena (OCI) ni muundo mwepesi, wazi wa utawala ulioundwa ndani ya Linux Foundation. Uainisho wa Picha wa OCI hufafanua viwango vya tasnia vya picha za kontena na fomati za wakati wa utekelezaji ili kuhakikisha kuwa injini za kontena zote zinaweza kuendesha picha za kontena zilizoundwa na zana yoyote ya ujenzi.

Ili kuweka programu katika vyombo, tunafunga programu yetu katika picha ya chombo na kuchapisha picha hiyo kwa sajili iliyoshirikiwa. Muda wa kukimbia wa chombo hurejesha picha hii kutoka kwa sajili, kuifungua, na kuendesha programu ndani yake.

Toleo la 2.3 la Spring Boot hutoa programu-jalizi za kuunda picha za OCI.

Docker ndio utekelezwaji wa kontena unaotumika sana, na tunatumia Docker katika mifano yetu, kwa hivyo marejeleo yote ya kontena yanayofuata katika nakala hii yatarejelea Docker.

Kujenga picha ya chombo kwa njia ya jadi

Kuunda picha za Docker kwa programu za Spring Boot ni rahisi sana kwa kuongeza maagizo machache kwenye faili ya Docker.

Kwanza tunaunda faili ya JAR inayoweza kutekelezwa na, kama sehemu ya maagizo ya faili ya Docker, kunakili faili inayoweza kutekelezwa ya JAR juu ya picha ya msingi ya JRE baada ya kutumia mipangilio muhimu.

Wacha tuunde programu yetu ya Spring Spring Initializr wenye utegemezi weblombokΠΈ actuator. Pia tunaongeza kidhibiti cha mapumziko ili kutoa API GETnjia.

Kuunda faili ya Docker

Kisha tunaweka programu hii kwenye chombo kwa kuongeza Dockerfile:

FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/application.jar"]

Faili yetu ya Docker ina picha ya msingi kutoka adoptopenjdk, ambayo juu yake tunakili faili yetu ya JAR na kisha kufungua bandari, 8080ambayo itasikiliza maombi.

Kujenga maombi

Kwanza unahitaji kuunda programu kwa kutumia Maven au Gradle. Hapa tunatumia Maven:

mvn clean package

Hii inaunda faili ya JAR inayoweza kutekelezwa kwa programu. Tunahitaji kubadilisha JAR hii inayoweza kutekelezwa kuwa picha ya Docker ili kuendesha injini ya Docker.

Kuunda picha ya chombo

Kisha tunaweka faili hii ya JAR inayoweza kutekelezwa kwenye picha ya Docker kwa kuendesha amri docker buildkutoka kwa saraka ya mizizi ya mradi iliyo na Dockerfile iliyoundwa mapema:

docker build  -t usersignup:v1 .

Tunaweza kuona picha yetu kwenye orodha kwa kutumia amri:

docker images 

Matokeo ya amri hapo juu ni pamoja na picha yetu usersignuppamoja na picha ya msingi, adoptopenjdkiliyoainishwa kwenye faili yetu ya Docker.

REPOSITORY          TAG                 SIZE
usersignup          v1                  249MB
adoptopenjdk        11-jre-hotspot      229MB

Tazama safu ndani ya picha ya chombo

Wacha tuangalie safu ya tabaka ndani ya picha. Tutatumia chombo  kupiga mbizi kutazama tabaka hizi:

dive usersignup:v1

Hapa kuna sehemu ya matokeo kutoka kwa amri ya Dive: 

Kuunda Picha za Docker Iliyoboreshwa kwa Maombi ya Boot ya Spring

Kama tunavyoona, safu ya maombi hufanya sehemu kubwa ya saizi ya picha. Tunataka kupunguza ukubwa wa safu hii katika sehemu zifuatazo kama sehemu ya uboreshaji wetu.

Kuunda picha ya chombo kwa kutumia Buildpack

Vifurushi vya mkutano (Vifurushi vya ujenzi) ni neno la jumla linalotumiwa na matoleo mbalimbali ya Mfumo kama Huduma (PAAS) ili kuunda picha ya kontena kutoka kwa msimbo wa chanzo. Ilizinduliwa na Heroku mnamo 2011 na tangu wakati huo imepitishwa na Cloud Foundry, Google App Engine, Gitlab, Knative na wengine kadhaa.

Kuunda Picha za Docker Iliyoboreshwa kwa Maombi ya Boot ya Spring

Faida ya vifurushi vya kujenga wingu

Moja ya faida kuu za kutumia Buildpack kuunda picha ni kwamba Mabadiliko ya usanidi wa picha yanaweza kudhibitiwa serikali kuu (mjenzi) na kuenezwa kwa programu zote kwa kutumia kijenzi.

Vifurushi vya ujenzi viliunganishwa kwa nguvu kwenye jukwaa. Cloud-Native Buildpacks hutoa usanifu katika mifumo yote kwa kutumia umbizo la picha la OCI, ambalo huhakikisha kwamba picha inaweza kuendeshwa na injini ya Docker.

Kutumia programu-jalizi ya Spring Boot

Programu-jalizi ya Spring Boot huunda picha za OCI kutoka kwa chanzo kwa kutumia Buildpack. Picha zinaundwa kwa kutumia bootBuildImagekazi (Gradle) au spring-boot:build-imagemalengo (Maven) na usakinishaji wa Docker wa ndani.

Tunaweza kubinafsisha jina la picha inayohitajika kusukuma kwa sajili ya Docker kwa kubainisha jina ndani image tag:

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <image>
      <name>docker.io/pratikdas/${project.artifactId}:v1</name>
    </image>
  </configuration>
</plugin>

Wacha tuitumie Maven kuifanya build-imagemalengo ya kuunda programu na kuunda picha ya chombo. Hatutumii Dockerfiles zozote kwa wakati huu.

mvn spring-boot:build-image

Matokeo yake yatakuwa kitu kama hiki:

[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:build-image (default-cli) @ usersignup ---
[INFO] Building image 'docker.io/pratikdas/usersignup:v1'
[INFO] 
[INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0%
.
.
.. [creator]     Adding label 'org.springframework.boot.version'
.. [creator]     *** Images (c311fe74ec73):
.. [creator]           docker.io/pratikdas/usersignup:v1
[INFO] 
[INFO] Successfully built image 'docker.io/pratikdas/usersignup:v1'

Kutoka kwa pato tunaona hivyo paketo Cloud-Native buildpackkutumika kuunda picha ya OCI inayofanya kazi. Kama hapo awali, tunaweza kuona picha iliyoorodheshwa kama picha ya Docker kwa kuendesha amri:

docker images 

Hitimisho:

REPOSITORY                             SIZE
paketobuildpacks/run                  84.3MB
gcr.io/paketo-buildpacks/builder      652MB
pratikdas/usersignup                  257MB

Kuunda picha ya kontena kwa kutumia Jib

Jib ni programu-jalizi ya kuunda picha kutoka Google ambayo hutoa mbinu mbadala ya kuunda picha ya kontena kutoka kwa msimbo wa chanzo.

Badilisha jib-maven-pluginkatika pom.xml:

      <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>2.5.2</version>
      </plugin>

Ifuatayo, tunaendesha programu-jalizi ya Jib kwa kutumia amri ya Maven kuunda programu na kuunda picha ya chombo. Kama hapo awali, hatutumii faili zozote za Docker hapa:

mvn compile jib:build -Dimage=<docker registry name>/usersignup:v1

Baada ya kutekeleza amri ya Maven hapo juu, tunapata matokeo yafuatayo:

[INFO] Containerizing application to pratikdas/usersignup:v1...
.
.
[INFO] Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, io.pratik.users.UsersignupApplication]
[INFO] 
[INFO] Built and pushed image as pratikdas/usersignup:v1
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete

Matokeo yanaonyesha kuwa picha ya chombo imeundwa na kuwekwa kwenye sajili.

Motisha na mbinu za kuunda picha zilizoboreshwa

Tuna sababu mbili kuu za uboreshaji:

  • Uzalishaji: Katika mfumo wa uratibu wa kontena, picha ya kontena hutolewa kutoka kwa sajili ya picha hadi kwa seva pangishi inayoendesha injini ya kontena. Utaratibu huu unaitwa kupanga. Kuvuta picha kubwa kutoka kwa sajili husababisha muda mrefu wa kuratibu katika mifumo ya upangaji wa kontena na muda mrefu wa kujenga katika mabomba ya CI.
  • usalama: Picha kubwa pia zina eneo kubwa zaidi la udhaifu.

Picha ya Docker ina safu ya tabaka, ambayo kila moja inawakilisha maagizo katika Dockerfile yetu. Kila safu inawakilisha delta ya mabadiliko katika safu ya msingi. Tunapovuta picha ya Docker kutoka kwa Usajili, inavutwa kwa tabaka na kuhifadhiwa kwenye mwenyeji.

Spring Boot hutumia "mafuta JAR" ndani kama umbizo la kifungashio chaguo-msingi. Tunapoangalia JAR nene, tunaona kwamba programu hufanya sehemu ndogo sana ya JAR nzima. Hii ndio sehemu inayobadilika mara nyingi. Salio lina tegemezi za Mfumo wa Spring.

Fomula ya uboreshaji inahusu kutenga programu katika kiwango tofauti na tegemezi za Mfumo wa Spring.

Safu tegemezi, ambayo huunda wingi wa faili nene ya JAR, inapakuliwa mara moja tu na kuhifadhiwa kwenye mfumo wa seva pangishi.

Safu nyembamba tu ya programu huvutwa wakati wa masasisho ya programu na upangaji wa kontena. kama inavyoonyeshwa kwenye mchoro huu:

Kuunda Picha za Docker Iliyoboreshwa kwa Maombi ya Boot ya Spring

Katika sehemu zifuatazo, tutaangalia jinsi ya kuunda picha hizi zilizoboreshwa kwa programu ya Spring Boot.

Kuunda Picha ya Kontena Iliyoboreshwa kwa Maombi ya Kianzi cha Spring Kwa kutumia Buildpack

Spring Boot 2.3 inasaidia kuweka tabaka kwa kutoa sehemu za faili nene ya JAR katika tabaka tofauti. Kipengele cha kuweka tabaka kimezimwa kwa chaguo-msingi na lazima kuwezeshwa kwa uwazi kwa kutumia programu-jalizi ya Spring Boot Maven:

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

Tutatumia usanidi huu kuunda picha yetu ya kontena kwanza na Buildpack na kisha na Docker katika sehemu zifuatazo.

Hebu tuzindue build-imageLengo la Maven la kuunda picha ya kontena:

mvn spring-boot:build-image

Ikiwa tutaendesha Dive ili kuona tabaka kwenye picha inayotokana, tunaweza kuona kwamba safu ya programu (iliyoainishwa kwa nyekundu) ni ndogo zaidi katika safu ya kilobyte ikilinganishwa na ile tuliyopata kwa kutumia umbizo nene la JAR:

Kuunda Picha za Docker Iliyoboreshwa kwa Maombi ya Boot ya Spring

Kuunda Picha ya Kontena Iliyoboreshwa kwa Maombi ya Boot ya Spring Kwa Kutumia Docker

Badala ya kutumia programu-jalizi ya Maven au Gradle, tunaweza pia kuunda picha ya Docker JAR na faili ya Docker.

Tunapotumia Docker, tunahitaji kufanya hatua mbili za ziada ili kutoa tabaka na kuzinakili kwenye picha ya mwisho.

Yaliyomo kwenye JAR iliyosababishwa baada ya kujenga kwa kutumia Maven iliyo na kuweka kuwezeshwa itaonekana kama hii:

META-INF/
.
BOOT-INF/lib/
.
BOOT-INF/lib/spring-boot-jarmode-layertools-2.3.3.RELEASE.jar
BOOT-INF/classpath.idx
BOOT-INF/layers.idx

Matokeo yanaonyesha JAR ya ziada iliyopewa jina spring-boot-jarmode-layertoolsΠΈ layersfle.idxfaili. Faili hii ya ziada ya JAR hutoa uwezo wa usindikaji wa tabaka, kama ilivyoelezwa katika sehemu inayofuata.

Kuchimba tegemezi kwenye tabaka za mtu binafsi

Kuangalia na kutoa tabaka kutoka kwa JAR yetu iliyowekewa safu, tunatumia sifa ya mfumo -Djarmode=layertoolskwa kuanzia spring-boot-jarmode-layertoolsJAR badala ya maombi:

java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar

Kuendesha amri hii hutoa pato lililo na chaguzi za amri zinazopatikana:

Usage:
  java -Djarmode=layertools -jar usersignup-0.0.1-SNAPSHOT.jar

Available commands:
  list     List layers from the jar that can be extracted
  extract  Extracts layers from the jar for image creation
  help     Help about any command

Pato linaonyesha amri listextractΠΈ helpс helpkuwa chaguomsingi. Wacha tuendeshe amri na listchaguo:

java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list
dependencies
spring-boot-loader
snapshot-dependencies
application

Tunaona orodha ya tegemezi ambazo zinaweza kuongezwa kama tabaka.

Tabaka chaguomsingi:

Jina la safu

yaliyomo

dependencies

utegemezi wowote ambao toleo lake halina SNAPSHOT

spring-boot-loader

Madarasa ya Upakiaji wa JAR

snapshot-dependencies

utegemezi wowote ambao toleo lake lina SNAPSHOT

application

madarasa ya maombi na rasilimali

Tabaka zimefafanuliwa ndani layers.idxfaili kwa mpangilio wanapaswa kuongezwa kwenye picha ya Docker. Safu hizi zimehifadhiwa kwenye seva pangishi baada ya urejeshaji wa kwanza kwa sababu hazibadiliki. Safu ya programu iliyosasishwa pekee ndiyo inayopakuliwa kwa seva pangishi, ambayo ni haraka kwa sababu ya saizi iliyopunguzwa .

Kuunda picha na vitegemezi vilivyotolewa katika tabaka tofauti

Tutajenga picha ya mwisho katika hatua mbili kwa kutumia njia inayoitwa mkusanyiko wa hatua nyingi . Katika hatua ya kwanza tutatoa utegemezi na katika hatua ya pili tutanakili utegemezi uliotolewa kwenye picha ya mwisho.

Wacha turekebishe Dockerfile yetu kwa muundo wa hatua nyingi:

# the first stage of our build will extract the layers
FROM adoptopenjdk:14-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

# the second stage of our build will copy the extracted layers
FROM adoptopenjdk:14-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

Tunahifadhi usanidi huu katika faili tofauti - Dockerfile2.

Tunaunda picha ya Docker kwa kutumia amri:

docker build -f Dockerfile2 -t usersignup:v1 .

Baada ya kuendesha amri hii tunapata pato lifuatalo:

Sending build context to Docker daemon  20.41MB
Step 1/12 : FROM adoptopenjdk:14-jre-hotspot as builder
14-jre-hotspot: Pulling from library/adoptopenjdk
.
.
Successfully built a9ebf6970841
Successfully tagged userssignup:v1

Tunaweza kuona kuwa picha ya Docker imeundwa na kitambulisho cha picha na kisha kutambulishwa.

Mwishowe, tunaendesha amri ya Dive kama hapo awali kukagua tabaka ndani ya picha ya Docker iliyotengenezwa. Tunaweza kutoa kitambulisho cha picha au lebo kama ingizo kwa amri ya Dive:

dive userssignup:v1

Kama unavyoona kwenye matokeo, safu iliyo na programu sasa ni KB 11 tu, na tegemezi zimehifadhiwa katika tabaka tofauti. 

Kuunda Picha za Docker Iliyoboreshwa kwa Maombi ya Boot ya Spring

Kuchimba tegemezi za ndani kwenye tabaka za mtu binafsi

Tunaweza kupunguza zaidi ukubwa wa kiwango cha programu kwa kutoa tegemezi zetu zozote maalum katika safu tofauti badala ya kuzifunga na programu kwa kuzitangaza katika ymlfaili inayofanana iliyopewa jina layers.idx:

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

Katika faili hii layers.idxtumeongeza utegemezi maalum unaoitwa, io.myorgiliyo na vitegemezi vya shirika vilivyopatikana kutoka kwa hazina iliyoshirikiwa.

Pato

Katika makala haya, tuliangalia kutumia Cloud-Native Buildpacks kuunda picha ya chombo moja kwa moja kutoka kwa msimbo wa chanzo. Hii ni njia mbadala ya kutumia Docker kuunda picha ya kontena kwa njia ya kawaida: kwanza kuunda faili nene inayoweza kutekelezwa ya JAR na kisha kuiweka kwenye picha ya chombo kwa kubainisha maagizo kwenye faili ya Docker.

Pia tuliangalia uboreshaji wa chombo chetu kwa kuwezesha kipengele cha kuweka tabaka ambacho huvuta vitegemezi katika tabaka tofauti ambazo zimewekwa kwenye seva pangishi na safu nyembamba ya programu hupakiwa wakati wa kuratibu katika injini za utekelezaji za kontena.

Unaweza kupata msimbo wote wa chanzo unaotumiwa katika makala Github .

Rejea ya amri

Hapa kuna muhtasari wa haraka wa amri tulizotumia katika nakala hii.

Kusafisha muktadha:

docker system prune -a

Kuunda picha ya chombo kwa kutumia faili ya Docker:

docker build -f <Docker file name> -t <tag> .

Tunaunda picha ya chombo kutoka kwa nambari ya chanzo (bila Dockerfile):

mvn spring-boot:build-image

Tazama tabaka za utegemezi. Kabla ya kuunda faili ya programu ya JAR, hakikisha kuwa kipengele cha kuweka tabaka kimewashwa kwenye programu-jalizi ya spring-boot-maven:

java -Djarmode=layertools -jar application.jar list

Kuchimba tabaka za utegemezi. Kabla ya kuunda faili ya programu ya JAR, hakikisha kuwa kipengele cha kuweka tabaka kimewashwa kwenye programu-jalizi ya spring-boot-maven:

 java -Djarmode=layertools -jar application.jar extract

Tazama orodha ya picha za kontena

docker images

Tazama upande wa kushoto ndani ya picha ya kontena (hakikisha kuwa zana ya kupiga mbizi imesakinishwa):

dive <image ID or image tag>

Chanzo: mapenzi.com