Optimeeritud Docker-piltide loomine Spring Boot rakendusele

Konteinerid on saanud eelistatud viisiks aplikatsioonide pakendamiseks koos kĂ”ikide tarkvara ja operatsioonisĂŒsteemi sĂ”ltuvustega ning nende edastamiseks erinevatesse keskkondadesse.

Selles artiklis kÀsitletakse erinevaid Spring Boot rakenduse konteineriseerimise viise:

  • Docker pildi loomine Docker faili abil,
  • OCI pildi loomine lĂ€htekoodist Cloud-Native Buildpacki abil,
  • ja pildi optimeerimine kĂ€itamise ajal JAR osade jagamise kaudu erinevatele tasemetele mitme taseme tööriistade abil.

 KoodinÀide

See artikkel sisaldab töötava koodi nÀidet GitHubis .

Konteinerite terminoloogia

Alustame artiklis kasutatavast konteinerite terminoloogiast:

  • Konteineri pilt (Container image): teatud formaadifail. Me konverteerime meie rakenduse konteineripildiks, kĂ€ivitades ehitusriista.
  • Konteiner: konteineripildi tĂ€idise eksemplar.
  • Konteineri mootor (Container engine): demon-protsess, mis vastutab konteineri kĂ€itamise eest.
  • Konteineri host (Container host): host-arvuti, millel konteineri mootor töötab.
  • Konteinerite register (Container registry): ĂŒhine asukoht, mida kasutatakse konteineripildi avaldamiseks ja levitamiseks.
  • OCI standard: Open Container Initiative (OCI) on kerge avatud haldusraamistik, mis on loodud Linux Foundationi raames. OCI pildispetsiifikatsioon mÀÀratleb tööstuse standardid konteineripiltide ja kĂ€ituskeskkondade formaatide jaoks, et tagada, et kĂ”ik konteinerimootorid suudavad kĂ€itada konteineripilte, mis on loodud mistahes ehitusriista abil.

Rakenduse konteinerisse panemiseks koostame meie rakenduse konteineripildiks ja avaldame selle pildi ĂŒhises registris. Konteineri kĂ€ituskeskkond tĂ”mbab selle pildi registrist, dekompileerib selle ja kĂ€ivitab rakenduse selle sees.

Spring Boot versioon 2.3 pakub pluginaid OCI piltide loomiseks.

Docker - kÔige laialdasemalt kasutatav konteinerite teostus, ja meie nÀidetes kasutame Dockerit, seega kÔik jÀrgmised viidatud konteinerid selles artiklis tÀhendavad Dockerit.

Konteineripildi loomine traditsioonilisel viisil

Docker piltide loomine Spring Boot rakenduste jaoks on vÀga lihtne, lisades paar juhist Docker failile.

Esiteks loome JAR-faili ja Docker-faili juhistes kopeerime JAR-faili JRE pÔhifaili peale, pÀrast vajalike seadete rakendamist.

LÀhme looma meie Springi rakendust Spring Initializr sÔltuvustega web, lombokja actuator. Me lisame ka rest-kontrolleri, et pakkuda API-d GETmeetodiga.

Docker-faili loomine

SeejÀrel paneme selle rakenduse konteinerisse, lisades Dockerfile:

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

Meie Docker-fail sisaldab pÔhifaili, mille peal adoptopenjdk, kuhu kopeerime oma JAR-faili ja seejÀrel avame pordi, 8080mis kuulab pÀringutele.

Rakenduse koostamine

Esiteks tuleb rakendus luua Maveniga vÔi Gradlega. Siin kasutame Mavenit:

mvn clean package

See loob rakenduse kĂ€ivitatava JAR-faili. Peame selle kĂ€ivitatava JAR-i muutma Docker-pildiks, et see töötaks Dockerite ekosĂŒsteemis.

Konteineri pildi loomine

SeejÀrel paneme selle kÀivitatava JAR-faili Docker-pilti, kÀivitades kÀsu docker buildprojekti juurkataloogist, mis sisaldab varem loodud Docker-faili:

docker build -t usersignup:v1 .

Saame oma pildi loendi vaatamiseks kasutada kÀsku:

docker images 

Ülaltoodud kĂ€su tulemus nĂ€itab meie pilti usersignupkoos pĂ”hifiltriga, adoptopenjdk, mis on meie Docker-failis mÀÀratud.

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

Konteineripildi kihtide vaatamine

Vaatame pilti kihtide virna. Kasutame vahend  dive, et vaadata neid kihte:

dive usersignup:v1

Siin on osa Dive kÀsu tulemustest: 

Optimeeritud Docker-piltide loomine Spring Boot rakendusele

Kuidas me nÀeme, et rakenduskiht vÔtab suure osa pildi suurusest. Soovime selle kihi suurust jÀrgnevates jaotistes optimeerimise raames vÀhendada.

Konteineri pildi loomine Buildpacki abil

Kogumispaketid (Buildpacks) on ĂŒldine mĂ”isted, mida kasutavad erinevad „Platvorm kui teenus” (PAAS) pakkumised konteineripildi loomiseks lĂ€htekoodist. See kĂ€ivitati Heroku poolt 2011. aastal ja on selle ajaga vastu vĂ”etud Cloud Foundry, Google App Engine, Gitlab, Knative ja mĂ”ne muu poolt.

Optimeeritud Docker-piltide loomine Spring Boot rakendusele

Pilve Buildpackide eelis

Üks peamisi eeliseid Buildpackide kasutamisel piltide loomiseks on see, et Kujunduse muutustega saab keskselt hallata (builder) ja jaotada kĂ”ikidele rakendustele, mis kasutavad builderit.

Kogumispaketid olid tihedalt seotud platvormiga. Cloud-Native Buildpacks tagavad standardimise platvormide vahel, toetades OCI pildiformaati, mis garanteerib, et pilti saab kÀitada Docker'i mootori abil.

Spring Boot plugina kasutamine

Spring Boot plugin loob OCI pilte allikakoodist, kasutades Buildpack'i. Pildid luuakse kasutades bootBuildImageĂŒlesandeid (Gradle) vĂ”i spring-boot:build-imageeesmĂ€rke (Maven) ja kohalikku Docker'i installatsiooni.

Saame konfigureerida pildi nime, mis on vajalik Docker registrisse saatmiseks, mÀÀrates nime 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>

Kasutame Mavenit, et tÀita build-imageeesmÀrk, et luua rakendus ja konteineripilt. Praegu me ei kasuta mingeid Docker'i faile.

mvn spring-boot:build-image

Tulemus on umbes jÀrgmine:

[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:build-image (default-cli) @ usersignup ---
[INFO] Ehitatakse pilti 'docker.io\/pratikdas\/usersignup:v1'
[INFO] 
[INFO]  > TÔmmates builderi pilti 'gcr.io\/paketo-buildpacks\/builder:base-platform-api-0.3' 0%
.
.
.. [creator]     Lisatakse silt 'org.springframework.boot.version'
.. [creator]     *** Pildid (c311fe74ec73):
.. [creator]           docker.io\/pratikdas\/usersignup:v1
[INFO] 
[INFO] Pilti 'docker.io\/pratikdas\/usersignup:v1' ehitati edukalt.

VÀljundist nÀeme, et paketo Cloud-Native buildpackkasutatakse töötava OCI pildi loomiseks. Nagu enne, saame pildi nÀha Docker pildina, kÀivitades kÀsu:

docker images 

KokkuvÔte:

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

Konteineripildi loomine Jibi abil

Jib on Google'i piltide loomise plugin, mis pakub alternatiivset meetodit konteineripildi loomiseks allikakoodist.

Seame ĂŒles jib-maven-pluginfailis pom.xml:

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

SeejÀrel kÀivitame Jibi plugina Maven'i kÀsu abil, et ehitada rakendus ja luua konteineripilt. Nagu enne, me ei kasuta mingeid Docker'i faile:

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

PĂ€rast ĂŒlaltoodud Maven'i kĂ€su tĂ€itmist saame jĂ€rgmise vĂ€ljundi:

[INFO] Rakenduse konteinerimine pratikdas/usersignup:v1...
.
.
[INFO] Konteineri sisenemispunkt seadistatud: [java, -cp, /app/resources:/app/classes:/app/libs/*, io.pratik.users.UsersignupApplication]
[INFO] 
[INFO] Pilt on ehitatud ja tÔugatud: pratikdas/usersignup:v1
[INFO] Tegevuste tÀitmine:
[INFO] [==============================] 100.0% tÀidetud

VÀljund nÀitab, et konteineri pilt on loodud ja salvestatud registrisse.

Motiivid ja meetodid optimeeritud piltide loomisel

Meil on kaks peamist pÔhjust optimeerimiseks:

  • TĂ”husus: konteinerite orkestreerimise sĂŒsteemis tĂ”mmatakse konteineri pilt registrist hostisse, kus konteinerimehhanism töötab. Seda protsessi nimetatakse planeerimiseks. Suurte piltide tĂ”mbamine registrist toob kaasa pika planeerimise aja konteinerite orkestreerimise sĂŒsteemides ja pika ehitusaega CI torudes.
  • Turvalisus: suured pildid omavad ka suuremat rĂŒnnaku pindala.

Docker'i pilt koosneb kihtide reost, millest igaĂŒks esindab kĂ€sku meie Dockerfile'is. Iga kiht esindab allpool oleva kihi muudatuste delta. Kui me tĂ”mbame Docker'i pilti registrist, tĂ”mmatakse see kihtidena ja kehtestatakse hostis.

Spring Boot kasutab "paksu JAR'i" vaikimisi pakendamisformaadina. Kui vaatame paksu JAR'i, nĂ€eme, et rakendus moodustab vĂ€ga vĂ€ikese osa kogu JAR-st. See on osa, mis muutub kĂ”ige sagedamini. ÜlejÀÀnud osa koosneb Spring Framework'i sĂ”ltuvustest. Optimeerimise valem keskendub rakenduse isoleerimisele eraldi kihis Spring Framework'i sĂ”ltuvustest.

SĂ”ltuvuste kiht, mis moodustab paksu JAR-faili peamise osa, laaditakse ainult ĂŒks kord ja kehtestatakse host-sĂŒsteemis.

Ainult rakenduse Ôhuke kiht tÔmmatakse rakenduse uuendamisel ja konteinerite planeerimisel,

nagu on nÀidatud selles diagrammis: JÀrgmistes osades vaatleme, kuidas luua neid optimeeritud pilte Spring Boot rakenduse jaoks.

Optimeeritud Docker-piltide loomine Spring Boot rakendusele

Optimeeritud konteineri pildi loomine Spring Boot rakendusele Buildpack'i abil

Spring Boot 2.3 toetab mitmekihilisust, tĂ”mmates paksu JAR-faili osad eraldi kihtidena. Vaikimisi on kihistamine vĂ€lja lĂŒlitatud ja see on vajalik selgesĂ”naliselt lubada Spring Boot Maven'i plugina abil:

Spring Boot 2.3 toetab mitmetasandilisust, eraldades paksu JAR-faili osad eraldi kihtidesse. Kihistamise funktsioon on vaikimisi keelatud ning tuleb selgelt aktiveerida Spring Boot Maven plugina abil:

org.springframework.boot
  spring-boot-maven-plugin
  
    
      true

Kasutame seda konfiguratsiooni meie konteineripildi loomiseks esmalt Buildpacki abil ja seejÀrel Dockeriga jÀrgnevates jaotistes.

KÀivitame build-imageMaveni eesmÀrgi konteineripildi loomiseks:

mvn spring-boot:build-image

Kui kÀivitame Dive'i, et nÀha tulemuspildis kihte, nÀeme, et rakenduse kiht (mÀrkitud punasega) on palju vÀiksem, ulatudes kilobaitideni, vÔrreldes sellega, mis meil oli, kasutades paksu JAR formaati:

Optimeeritud Docker-piltide loomine Spring Boot rakendusele

Optimeeritud konteineripildi loomine Spring Booti rakenduse jaoks Dockeriga

Juhul, kui me ei kasuta Maveni ega Gradle'i pluginat, saame luua ka mitmekihilise JAR Dockeripildi Dockerifaili abil.

Kui kasutame Dockerit, peame tegemiseks kahe tÀiendava sammu, et kihte eraldada ja need lÔplikku pilti kopeerida.

Maveni abil ehitatud JAR-i sisu, kus on sisse lĂŒlitatud kihistumise funktsioon, nĂ€eb vĂ€lja jĂ€rgnev:

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

VÀljundis kuvatakse tÀiendav JAR nimega spring-boot-jarmode-layertoolsja layersfle.idxfail. See tÀiendav JAR-fail vÔimaldab mitmekihilist töötlemist, nagu on kirjeldatud jÀrgmises jaotises.

SÔltuvuste eraldamine eraldi kihtidesse

Kihte meie mitmekihilisest JAR-ist vaatamiseks ja eraldamiseks kasutame sĂŒsteemi omadust -Djarmode=layertoolsrakenduse asemel JAR-i kĂ€itamiseks: spring-boot-jarmode-layertoolsjava -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar

Selle kÀsu tÀitmine annab vÀljundi, mis sisaldab saadaval olevaid kÀsklusi:

Kasutus: java -Djarmode=layertools -jar usersignup-0.0.1-SNAPSHOT.jarSaadaval kÀsud: list Loetleb kihid jar-ist, mida saab eraldada extract Eristab kihte jar-ist pildi loomise eesmÀrgil help Abi iga kÀsu kohta

VÀljal on nÀha kÀsklused

extract loend, olema vaikimisi. KÀitame kÀsku koosja helpjot helpvalikuga: loendjava -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list

dependencies
spring-boot-loader
snapshot-dependencies
application
NÀeme loetelu sÔltuvustest, mida saab lisada kihtidena.

Vaikimisi kihid:

Kihi nimi

igal sÔltuvusel, mille versioon ei sisalda SNAPSHOT-i

Sisukord

sÔltuvused

spring-boot-loader

JAR-i laadijate klassid

snapshot-dependencies

igal sÔltuvusel, mille versioon sisaldab SNAPSHOT-i

rakendus

rakenduse klassid ja ressursid

rakenduste klassid ja ressursid

Kihid on mÀÀratletud layers.idxfailis jÀrjekorras, milles neid tuleks Docker-pildi lisamiseks kasutada. Need kihid vahelduvad hostis pÀrast esmakordset allalaadimist, kuna need ei muutu. Hostile laaditakse ainult rakenduse uuendatud kiht, mis toimub kiiremini vÀiksema suuruse tÔttu. .

Pildi koostamine sÔltuvustest, mis on allalaaditud eraldi kihtidena.

Loome lÔpliku pildi kahes etapis, kasutades meetodit, mida nimetatakse mitmeastmeliseks ehitamiseks . Esimeses etapis lahti vÔtame sÔltuvused ja teises etapis kopeerime lahti vÔetud sÔltuvused lÔplikku pilti.

Muutame meie Docker faili mitmeastmelise ehituse jaoks:

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

Salvestame selle konfiguratsiooni eraldi faili — Dockerfile2.

Kogume Docker pilti kÀsu abil:

docker build -f Dockerfile2 -t usersignup:v1 .

PÀrast selle kÀsu tÀitmist saame jÀrgmise vÀljundi:

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

NÀeme, et Docker pilt luuakse pildi ID-ga ja seejÀrel mÀrgistatakse.

LÔpuks kÀivitame Dive kÀsu, nagu eelnevalt, et kontrollida kihte genereeritud Docker pildi sees. Saame mÀÀrata pildi ID vÔi etiketi Dive kÀsu sisendiks:

dive userssignup:v1

VĂ€ljundi pĂ”hjal on rakendust sisaldav kiht nĂŒĂŒd vaid 11 KB ja sĂ”ltuvused vahelduvad eraldi kihtides. 

Optimeeritud Docker-piltide loomine Spring Boot rakendusele

Sisemiste sÔltuvuste allalaadimine eraldi kihtidena

Saame edasise rakenduse kihi suuruse vÀhendamiseks lahti vÔtta kÔik meie kasutajate sÔltuvused eraldi kihina, selle asemel et neid koos rakendusega pakkida, deklareerides need ymlsarnases failis nimega 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/"

Selles failis layers.idxoleme lisanud kohandatava sĂ”ltuvuse nimega, io.myorgmis sisaldab organisatsiooni sĂ”ltuvusi, saadud ĂŒldisest hoidlast.

KokkuvÔte

Selles artiklis kÀsitleme Cloud-Native Buildpackide kasutamist konteineripildi loomisel otse lÀhtekoodist. See on alternatiiv Dockerile, kus konteineripilt luuakse tavapÀrasel viisil: esmalt luuakse paks JAR-fail ja seejÀrel pakitakse see konteineripildiks, andes juhised Dockerifailis.

KĂ€sitlesime ka meie konteineri optimeerimist, hĂ”lmates kihistamisfunktsiooni, mis eraldab sĂ”ltuvused eraldi kihtidesse, mida vahemĂ€lus hoitakse, ja rakenduse Ă”huke kiht laaditakse ĂŒles konteinerite tĂ€itmise mehhanismide kavandamise ajal.

Kogu artiklis kasutatud lÀhtekood on saadaval Github .

KĂ€skude juhend

Siin on kokkuvÔte kÀskudest, mida kasutasime selles artiklis kiireks tutvumiseks.

Konteksti puhastamine:

docker system prune -a

Konteineripildi loomine Dockerifaili abil:

docker build -f  -t  .

Konteineripildi koostamine lÀhtekoodist (ilma Dockerifailita):

mvn spring-boot:build-image

SÔltuvuste kihtide vaatamine. Enne rakenduse JAR-faili koostamist veenduge, et kihistamise funktsioon on lubatud spring-boot-maven-pluginis:

java -Djarmode=layertools -jar application.jar list

SÔltuvuste kihtide vÀljavÔtmine. Enne rakenduse JAR-faili koostamist veenduge, et kihistamise funktsioon on lubatud spring-boot-maven-pluginis:

 java -Djarmode=layertools -jar application.jar extract

Konteineripiltide loendi vaatamine

docker images

Konteineripildi sees olevate kihtide vaatamine (veenduge, et teil on installitud sukeldumise tööriist):

dive

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster