Adeiladu Delweddau Dociwr wedi'u Optimeiddio ar gyfer Cais Cist Gwanwyn

Mae cynwysyddion wedi dod yn ddull dewisol o becynnu rhaglen gyda'i holl ddibyniaethau ar feddalwedd a system weithredu ac yna eu danfon i wahanol amgylcheddau.

Mae'r erthygl hon yn ymdrin â gwahanol ffyrdd o gynnwys cymhwysiad Spring Boot:

  • adeiladu delwedd docwr gan ddefnyddio dockerfile,
  • adeiladu delwedd OCI o'r ffynhonnell gan ddefnyddio Cloud-Native Buildpack,
  • ac optimeiddio delweddau ar amser rhedeg trwy wahanu rhannau JAR i wahanol lefelau gan ddefnyddio offer haenog.

 Enghraifft Cod

Mae enghraifft o god gweithredol yn cyd-fynd â'r erthygl hon ar GitHub .

Terminoleg cynhwysydd

Byddwn yn dechrau gyda'r derminoleg cynhwysydd a ddefnyddir trwy gydol yr erthygl:

  • Delwedd cynhwysydd: ffeil o fformat penodol. Rydym yn trosi ein cais yn ddelwedd cynhwysydd trwy redeg yr offeryn adeiladu.
  • Cynhwysydd: Enghraifft gweithredadwy o ddelwedd y cynhwysydd.
  • Injan cynhwysydd: Y broses daemon sy'n gyfrifol am redeg y cynhwysydd.
  • Gwesteiwr cynhwysydd: Y peiriant gwesteiwr y mae injan y cynhwysydd yn rhedeg arno.
  • Cofrestrfa cynhwysydd: Y lleoliad cyffredinol a ddefnyddir i gyhoeddi a dosbarthu delwedd y cynhwysydd.
  • OCI safonolMenter Cynhwysydd Agored (OCI) yn fframwaith rheoli ysgafn, ffynhonnell agored a ffurfiwyd gan y Linux Foundation. Mae Manyleb Delwedd OCI yn diffinio safonau diwydiant ar gyfer fformatau delwedd cynhwysydd a'r amser rhedeg i sicrhau y gall pob injan cynhwysydd redeg delweddau cynhwysydd a grëwyd gan unrhyw offeryn adeiladu.

I amwyso cais, rydym yn lapio ein cais mewn delwedd cynhwysydd ac yn cyhoeddi'r ddelwedd honno i'r gofrestrfa gyhoeddus. Mae amser rhedeg y cynhwysydd yn adfer y ddelwedd hon o'r gofrestrfa, yn ei dadbacio, ac yn rhedeg y rhaglen y tu mewn iddi.

Mae fersiwn 2.3 o Spring Boot yn darparu ategion ar gyfer adeiladu delweddau OCI.

Docker yw'r gweithredu cynhwysydd a ddefnyddir amlaf, ac rydym yn defnyddio Docker yn ein henghreifftiau, felly bydd yr holl gyfeiriadau cynhwysydd dilynol yn yr erthygl hon yn cyfeirio at Docker.

Adeiladu delwedd cynhwysydd yn y ffordd draddodiadol

Mae adeiladu delweddau Docker ar gyfer cymwysiadau Spring Boot yn hawdd iawn trwy ychwanegu ychydig o gyfarwyddiadau i'ch Dockerfile.

Yn gyntaf rydym yn creu JAR gweithredadwy ac, fel rhan o gyfarwyddiadau Dockerfile, yn copïo'r JAR gweithredadwy ar ben y ddelwedd JRE sylfaenol ar ôl cymhwyso'r addasiadau angenrheidiol.

Gadewch i ni greu ein cais Gwanwyn ymlaen Cychwynnol y Gwanwyn gyda dibyniaethau weblombokи actuator. Rydym hefyd yn ychwanegu rheolydd gorffwys i ddarparu API ag ef GETdull.

Creu Ffeil Docker

Yna rydyn ni'n gosod y cais hwn mewn cynhwysydd trwy ychwanegu Dockerfile:

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

Mae ein Dockerfile yn cynnwys delwedd sylfaenol, o adoptopenjdk, ar ben hynny rydym yn copïo ein ffeil JAR ac yna'n agor y porthladd, 8080a fydd yn gwrando ar geisiadau.

Cynulliad cais

Yn gyntaf mae angen i chi greu cymhwysiad gan ddefnyddio Maven neu Gradle. Dyma ni'n defnyddio Maven:

mvn clean package

Mae hyn yn creu ffeil JAR gweithredadwy ar gyfer y cais. Mae angen i ni drosi'r JAR gweithredadwy hwn yn ddelwedd Dociwr i redeg ar injan y Dociwr.

Creu delwedd cynhwysydd

Yna rydyn ni'n rhoi'r gweithredadwy JAR hwn yn y ddelwedd Docker trwy redeg y gorchymyn docker buildo gyfeiriadur gwraidd y prosiect sy'n cynnwys y Dockerfile a grëwyd yn gynharach:

docker build  -t usersignup:v1 .

Gallwn weld ein delwedd yn y rhestr gyda'r gorchymyn:

docker images 

Mae allbwn y gorchymyn uchod yn cynnwys ein delwedd usersignupynghyd â'r ddelwedd sylfaenol, adoptopenjdka nodir yn ein Dockerfile.

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

Gweld haenau y tu mewn i ddelwedd cynhwysydd

Gadewch i ni edrych ar y pentwr o haenau y tu mewn i'r ddelwedd. Byddwn yn defnyddio инструмент  plymio, i weld yr haenau hyn:

dive usersignup:v1

Dyma ran o allbwn y gorchymyn Dive: 

Adeiladu Delweddau Dociwr wedi'u Optimeiddio ar gyfer Cais Cist Gwanwyn

Fel y gallwn weld, mae haen y cais yn rhan sylweddol o faint y ddelwedd. Rydym am leihau maint yr haen hon yn yr adrannau canlynol fel rhan o'n optimeiddio.

Adeiladu delwedd cynhwysydd gyda Buildpack

Pecynnau cynulliad (Pecynnau adeiladu) yn derm generig a ddefnyddir gan amrywiol offrymau Platfform fel Gwasanaeth (PAAS) i greu delwedd cynhwysydd o god ffynhonnell. Fe'i lansiwyd gan Heroku yn 2011 ac ers hynny mae wedi'i fabwysiadu gan Cloud Foundry, Google App Engine, Gitlab, Knative ac ychydig o rai eraill.

Adeiladu Delweddau Dociwr wedi'u Optimeiddio ar gyfer Cais Cist Gwanwyn

Mantais Pecynnau Adeiladu Cwmwl

Un o brif fanteision defnyddio Buildpack i adeiladu delweddau yw hynny gellir rheoli newidiadau cyfluniad delwedd yn ganolog (adeiladwr) a'u lluosogi i bob rhaglen sy'n defnyddio'r adeiladwr.

Roedd y pecynnau adeiladu wedi'u cysylltu'n agos â'r platfform. Mae Cloud-Native Buildpacks yn darparu safoni ar draws llwyfannau trwy gefnogi fformat delwedd OCI, sy'n sicrhau y gall y ddelwedd gael ei rhedeg gan yr injan Docker.

Gan ddefnyddio'r Ategyn Cist Gwanwyn

Mae ategyn Spring Boot yn adeiladu delweddau OCI o'r ffynhonnell gan ddefnyddio Buildpack. Mae delweddau'n cael eu creu gan ddefnyddio bootBuildImagetasgau (Gradle) neu spring-boot:build-imagetarged (Maven) a gosodiad Docker lleol.

Gallwn addasu enw'r ddelwedd y mae angen i ni ei gwthio i gofrestrfa'r Docker trwy nodi'r enw ynddo 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>

Gadewch i ni ddefnyddio Maven i weithredu build-imagenodau ar gyfer creu cymhwysiad a chreu delwedd cynhwysydd. Nid ydym yn defnyddio unrhyw Dockerfiles ar hyn o bryd.

mvn spring-boot:build-image

Y canlyniad fydd rhywbeth fel hyn:

[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'

O'r allbwn, gwelwn hynny paketo Cloud-Native buildpacka ddefnyddir i greu delwedd OCI sy'n gweithio. Fel o'r blaen, gallwn weld y ddelwedd a restrir fel delwedd Docker trwy redeg y gorchymyn:

docker images 

Casgliad:

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

Creu Delwedd Cynhwysydd gyda Jib

Mae Jib yn ategyn awduro delwedd gan Google sy'n darparu dull amgen o greu delwedd cynhwysydd o'r ffynhonnell.

Addasu jib-maven-pluginyn pom.xml:

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

Nesaf, rydym yn rhedeg yr ategyn Jib gan ddefnyddio'r gorchymyn Maven i adeiladu'r cymhwysiad a chreu delwedd y cynhwysydd. Fel o'r blaen, nid ydym yn defnyddio unrhyw Dockerfiles yma:

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

Ar ôl gweithredu'r gorchymyn Maven uchod, rydym yn cael yr allbwn canlynol:

[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

Mae'r allbwn yn dangos bod delwedd y cynhwysydd wedi'i chreu a'i gosod yn y gofrestrfa.

Cymhellion a dulliau ar gyfer creu delweddau wedi'u hoptimeiddio

Mae gennym ddau brif reswm dros optimeiddio:

  • Cynhyrchiant: Mewn system offeryniaeth cynhwysydd, tynnir delwedd cynhwysydd o'r gofrestr ddelwedd i'r gwesteiwr sy'n rhedeg yr injan cynhwysydd. Yr enw ar y broses hon yw cynllunio. Mae tynnu delweddau mawr o'r gofrestrfa yn arwain at amseroedd amserlennu hir mewn systemau offeryniaeth cynwysyddion ac amseroedd adeiladu hir mewn piblinellau CI.
  • diogelwch: mae gan ddelweddau mawr hefyd ardal fawr ar gyfer gwendidau.

Mae delwedd Dociwr yn cynnwys pentwr o haenau, pob un yn cynrychioli datganiad yn ein Dockerfile. Mae pob haen yn cynrychioli delta newidiadau yn yr haen waelodol. Pan dynnwn ddelwedd Docker o'r gofrestrfa, caiff ei dynnu mewn haenau a'i storio ar y gwesteiwr.

Defnyddiau Spring Boot "JAR braster" yn fel y fformat pecynnu rhagosodedig. Pan edrychwn ar JAR braster, gwelwn fod y cais yn rhan fach iawn o'r JAR cyfan. Dyma'r rhan sy'n newid fwyaf. Mae'r gweddill yn cynnwys dibyniaethau Fframwaith y Gwanwyn.

Mae'r fformiwla optimeiddio yn canolbwyntio ar ynysu'r cymhwysiad ar lefel ar wahân i ddibyniaethau Fframwaith y Gwanwyn.

Dim ond unwaith y caiff yr haen dibyniaeth sy'n ffurfio swmp y ffeil JAR drwchus ei lawrlwytho a'i storio ar y system westeiwr.

Dim ond haen denau o'r app sy'n cael ei thynnu yn ystod diweddariadau app ac amserlennu cynwysyddion, fel y dangosir yn y diagram hwn:

Adeiladu Delweddau Dociwr wedi'u Optimeiddio ar gyfer Cais Cist Gwanwyn

Yn yr adrannau canlynol, byddwn yn edrych ar sut i greu'r delweddau optimaidd hyn ar gyfer cymhwysiad Spring Boot.

Adeiladu Delwedd Cynhwysydd Wedi'i Optimeiddio ar gyfer Cais Cist Gwanwyn gyda Buildpack

Mae Spring Boot 2.3 yn cefnogi haenu trwy dynnu rhannau o ffeil JAR trwchus yn haenau ar wahân. Mae'r nodwedd haenu wedi'i hanalluogi yn ddiofyn ac mae angen ei galluogi'n benodol gan ddefnyddio'r ategyn Spring Boot Maven:

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

Byddwn yn defnyddio'r cyfluniad hwn i adeiladu ein delwedd cynhwysydd yn gyntaf gyda Buildpack ac yna gyda Docker yn yr adrannau canlynol.

Gadewch i ni redeg build-imageTarged Maven i greu delwedd cynhwysydd:

mvn spring-boot:build-image

Os byddwn yn rhedeg Dive i weld yr haenau yn y ddelwedd sy'n deillio o hynny, gallwn weld bod yr haen cais (wedi'i chylchu mewn coch) yn llawer llai yn yr ystod kilobyte o'i gymharu â'r hyn a gawsom gan ddefnyddio'r fformat JAR trwchus:

Adeiladu Delweddau Dociwr wedi'u Optimeiddio ar gyfer Cais Cist Gwanwyn

Adeiladu Delwedd Cynhwysydd Wedi'i Optimeiddio ar gyfer Cais Cist Gwanwyn gyda Docker

Yn lle defnyddio ategyn Maven neu Gradle, gallwn hefyd greu delwedd Docker JAR haenog gyda ffeil Docker.

Pan ddefnyddiwn Docker, mae angen inni gymryd dau gam ychwanegol i dynnu'r haenau a'u copïo i'r ddelwedd derfynol.

Bydd cynnwys y JAR dilynol ar ôl adeiladu gyda Maven gyda haenau wedi'u galluogi yn edrych fel hyn:

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

Mae'r allbwn yn dangos JAR ychwanegol wedi'i enwi spring-boot-jarmode-layertoolsи layersfle.idxffeil. Mae'r ffeil JAR ychwanegol hon yn darparu galluoedd haenu, fel y disgrifir yn yr adran nesaf.

Echdynnu dibyniaethau ar haenau ar wahân

I weld a thynnu haenau o'n JAR haenog, rydym yn defnyddio eiddo'r system -Djarmode=layertoolsi ddechrau spring-boot-jarmode-layertoolsJAR yn lle cais:

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

Mae rhedeg y gorchymyn hwn yn cynhyrchu allbwn sy'n cynnwys yr opsiynau gorchymyn sydd ar gael:

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

Mae'r allbwn yn dangos y gorchmynion listextractи helpс helpfod y rhagosodedig. Gadewch i ni redeg y gorchymyn gyda listopsiwn:

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

Rydym yn gweld rhestr o ddibyniaethau y gellir eu hychwanegu fel haenau.

Haenau yn ddiofyn:

Enw haen

Cynnwys

dependencies

unrhyw ddibyniaeth nad yw ei fersiwn yn cynnwys SNAPSHOT

spring-boot-loader

Dosbarthiadau Llwythwyr JAR

snapshot-dependencies

unrhyw ddibyniaeth y mae ei fersiwn yn cynnwys SNAPSHOT

application

dosbarthiadau cais ac adnoddau

Diffinnir haenau yn layers.idxffeil yn y drefn y dylid eu hychwanegu at ddelwedd y Docker. Mae'r haenau hyn yn cael eu storio ar y gwesteiwr ar ôl y cyrch cyntaf oherwydd nad ydynt yn newid. Dim ond yr haen cais wedi'i diweddaru sy'n cael ei lawrlwytho i'r gwesteiwr, sy'n gyflymach oherwydd y maint llai .

Adeiladu delwedd gyda dibyniaethau wedi'u tynnu i haenau ar wahân

Byddwn yn adeiladu'r ddelwedd derfynol mewn dau gam gan ddefnyddio dull o'r enw cynulliad aml-gam . Yn y cam cyntaf byddwn yn echdynnu'r dibyniaethau ac yn yr ail gam byddwn yn copïo'r dibyniaethau a echdynnwyd i'r rownd derfynol.

Gadewch i ni addasu ein Dockerfile ar gyfer adeilad aml-gam:

# 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"]

Rydym yn cadw'r ffurfwedd hon mewn ffeil ar wahân - Dockerfile2.

Rydym yn adeiladu delwedd y Docker gan ddefnyddio'r gorchymyn:

docker build -f Dockerfile2 -t usersignup:v1 .

Ar ôl gweithredu'r gorchymyn hwn, rydym yn cael yr allbwn canlynol:

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

Gallwn weld bod delwedd y Docker yn cael ei chreu gydag ID delwedd ac yna'n cael ei thagio.

Yn olaf, rydym yn rhedeg y gorchymyn Dive fel o'r blaen i edrych ar yr haenau y tu mewn i'r ddelwedd Docker a gynhyrchir. Gallwn ddarparu ID delwedd neu dag fel mewnbwn i'r gorchymyn Dive:

dive userssignup:v1

Fel y gallwch weld o'r allbwn, dim ond 11 KB yw'r haen sy'n cynnwys y cymhwysiad bellach ac mae'r dibyniaethau wedi'u storio mewn haenau ar wahân. 

Adeiladu Delweddau Dociwr wedi'u Optimeiddio ar gyfer Cais Cist Gwanwyn

Echdynnu dibyniaethau mewnol ar haenau ar wahân

Gallwn leihau maint yr haen ymgeisio ymhellach trwy dynnu unrhyw un o'n dibyniaethau arfer i mewn i haen ar wahân yn lle eu pecynnu gyda'r cais trwy eu datgan yn ymlffeil tebyg wedi'i henwi 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/"

Yn y ffeil hon layers.idxrydym wedi ychwanegu dibyniaeth arfer o'r enw, io.myorgsy'n cynnwys dibyniaethau sefydliad a adalwyd o'r gadwrfa a rennir.

Allbwn

Yn yr erthygl hon, fe wnaethom edrych ar ddefnyddio Cloud-Native Buildpacks i adeiladu delwedd cynhwysydd yn uniongyrchol o'r ffynhonnell. Mae hwn yn ddewis arall yn lle defnyddio Docker i greu delwedd cynhwysydd yn y ffordd arferol: yn gyntaf, mae ffeil JAR gweithredadwy drwchus yn cael ei chreu ac yna'n cael ei phecynnu i ddelwedd cynhwysydd trwy nodi'r cyfarwyddiadau yn y Dockerfile.

Fe wnaethom hefyd edrych ar optimeiddio ein cynhwysydd trwy gynnwys nodwedd haenu sy'n tynnu dibyniaethau i haenau ar wahân sy'n cael eu storio ar y gwesteiwr ac mae haen gais denau yn cael ei llwytho ar amser amserlennu ym mheiriannau gweithredu'r cynhwysydd.

Gallwch ddod o hyd i'r holl god ffynhonnell a ddefnyddiwyd yn yr erthygl yn Github .

Cyfeirnod Gorchymyn

Dyma grynodeb o'r gorchmynion a ddefnyddiwyd gennym yn yr erthygl hon ar gyfer cyfeiriad cyflym.

Clirio cyd-destun:

docker system prune -a

Adeiladu delwedd cynhwysydd gyda Dockerfile:

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

Adeiladu delwedd cynhwysydd o'r ffynhonnell (heb Dockerfile):

mvn spring-boot:build-image

Gweld haenau dibyniaeth. Cyn adeiladu ffeil jar y cais, gwnewch yn siŵr bod y nodwedd haenu wedi'i galluogi yn y spring-boot-maven-plugin:

java -Djarmode=layertools -jar application.jar list

Detholiad haenau dibyniaeth. Cyn adeiladu ffeil jar y cais, gwnewch yn siŵr bod y nodwedd haenu wedi'i galluogi yn y spring-boot-maven-plugin:

 java -Djarmode=layertools -jar application.jar extract

Gweld Rhestr o Delweddau Cynhwysydd

docker images

Gweld ar y chwith y tu mewn i ddelwedd y cynhwysydd (gwnewch yn siŵr bod yr offeryn plymio wedi'i osod):

dive <image ID or image tag>

Ffynhonnell: hab.com