Spring Boot aplikazio baterako Docker Irudi optimizatuak eraikitzea
Edukiontziak aplikazio bat bere software eta sistema eragilearen menpekotasun guztiekin ontziratzeko baliabiderik hobetsi bihurtu dira eta gero ingurune ezberdinetara entregatzeko.
Artikulu honek Spring Boot aplikazio bat edukiontziratzeko modu desberdinak biltzen ditu:
Docker irudi bat eraikitzea dockerfile bat erabiliz,
Iturburutik OCI irudi bat eraikitzea Cloud-Native Buildpack erabiliz,
eta irudien optimizazioa exekuzioan JAR zatiak maila ezberdinetan bereiziz geruzadun tresnak erabiliz.
Kode Adibidea
Artikulu honek lan-kodearen adibide batekin batera doa GitHub-en .
Edukiontziaren terminologia
Artikuluan zehar erabilitako edukiontziaren terminologiarekin hasiko gara:
Edukiontziaren irudia: formatu zehatz bateko fitxategia. Gure aplikazioa edukiontzi-irudi bihurtzen dugu eraikitze-tresna exekutatuz.
Edukiontzi motorra: edukiontzia exekutatzeko ardura duen deabru-prozesua.
Edukiontziaren ostalaria: edukiontzi-motorra martxan dagoen makina ostalaria.
Edukiontzien erregistroa: edukiontziaren irudia argitaratzeko eta banatzeko erabiltzen den kokapen orokorra.
OCI estandarra: Edukiontzi Irekiaren Ekimena (OCI) Linux Fundazioak eratutako kode irekiko kudeaketa-esparru arina da. OCI Irudien Zehaztapenak industriako estandarrak definitzen ditu edukiontzien irudi formatuen eta exekuzio-denbora, edukiontzi-motor guztiek edozein eraikuntza tresnak sortutako edukiontzien irudiak exekutatu ditzaketela ziurtatzeko.
Aplikazio bat edukiontziratzeko, gure aplikazioa edukiontzi-irudi batean biltzen dugu eta irudi hori erregistro publikoan argitaratzen dugu. Edukiontziaren exekuzio-denborak irudi hau erregistrotik berreskuratzen du, deskonprimitu eta aplikazioa bere barruan exekutatzen du.
Spring Boot-en 2.3 bertsioak OCI irudiak eraikitzeko pluginak eskaintzen ditu.
Docker gehien erabiltzen den edukiontziaren inplementazioa da, eta Docker erabiltzen dugu gure adibideetan, beraz, artikulu honetako ondorengo edukiontzien erreferentzia guztiak Docker-era aipatuko dira.
Edukiontziaren irudia modu tradizionalean eraikitzea
Spring Boot aplikazioetarako Docker irudiak sortzea oso erraza da zure Dockerfile-ra argibide batzuk gehituta.
Lehenik eta behin, JAR exekutagarri bat sortzen dugu eta, Dockerfile argibideen zati gisa, JAR exekutagarria oinarrizko JRE irudiaren gainean kopiatu behar dugu beharrezko pertsonalizazioak aplikatu ondoren.
Sortu dezagun gure Spring aplikazioa Udaberriko Initializr mendekotasunekin web, lombokΠΈ actuator. Gainera, atseden kontrolagailu bat gehitzen dugu API bat eskaintzeko GETmetodoa.
Dockerfile bat sortzea
Ondoren, aplikazio hau edukiontzi batean jartzen dugu gehituz Dockerfile:
Gure Dockerfile-k oinarrizko irudi bat dauka adoptopenjdk, horren gainean gure JAR fitxategia kopiatzen dugu eta gero portua irekitzen dugu, 8080eskaerak entzungo dituena.
Aplikazioen muntaia
Lehenik eta behin aplikazio bat sortu behar duzu Maven edo Gradle erabiliz. Hemen Maven erabiltzen ari gara:
mvn clean package
Honek JAR fitxategi exekutagarri bat sortzen du aplikaziorako. JAR exekutagarri hau Docker irudi batean bihurtu behar dugu Docker motorra exekutatzeko.
Sortu edukiontziaren irudia
Ondoren, JAR exekutagarri hau Docker irudian jartzen dugu komandoa exekutatuz docker buildLehenago sortutako Dockerfile-a duen proiektuaren erro-direktoriotik:
docker build -t usersignup:v1 .
Gure irudia zerrendan ikus dezakegu komandoarekin:
docker images
Goiko komandoaren irteerak gure irudia barne hartzen du usersignupoinarrizko irudiarekin batera, adoptopenjdkgure Dockerfile-n zehaztuta.
REPOSITORY TAG SIZE
usersignup v1 249MB
adoptopenjdk 11-jre-hotspot 229MB
Ikusi edukiontzi-irudi baten barruko geruzak
Ikus dezagun irudiaren barruko geruza pila. Erabiliko dugu tresna urperatu, geruza hauek ikusteko:
dive usersignup:v1
Hona hemen Dive komandoaren irteeraren zati bat:
Ikus dezakegunez, aplikazio geruzak irudiaren tamainaren zati garrantzitsu bat osatzen du. Geruza honen tamaina murriztu nahi dugu hurrengo ataletan gure optimizazioaren zati gisa.
Edukiontzi-irudia eraikitzea Buildpack-ekin
Muntaketa paketeak (Eraikitzeko paketeak) Platform as a Service (PAAS) eskaintzak erabiltzen duten termino generikoa da iturburu-kodetik edukiontzi-irudia sortzeko. Herokuk 2011n jarri zuen abian eta harrezkero Cloud Foundry, Google App Engine, Gitlab, Knative eta beste batzuek hartu dute.
Cloud Build paketeen abantaila
Irudiak eraikitzeko Buildpack erabiltzearen abantaila nagusietako bat hori da irudien konfigurazio-aldaketak zentralki kudeatu daitezke (eraikitzailea) eta aplikazio guztietara hedatu eraikitzailea erabiliz.
Eraikitzeko paketeak plataformari estu lotuta zeuden. Cloud-Native Buildpack-ek plataforma guztietan estandarizazioa eskaintzen du OCI irudi formatua onartzen duelarik, eta horrek bermatzen du irudia Docker motorrak exekutatu ahal izango duela.
Spring Boot Plugin-a erabiliz
Spring Boot pluginak OCI irudiak sortzen ditu iturburutik Buildpack erabiliz. Irudiak erabiliz sortzen dira bootBuildImagezereginak (Gradle) edo spring-boot:build-imagexede (Maven) eta Docker instalazio lokala.
Docker erregistrora bidali behar dugun irudiaren izena pertsonaliza dezakegu izena zehaztuz image tag:
Erabili dezagun Maven exekutatzeko build-imageaplikazio bat sortzeko eta edukiontziaren irudia sortzeko helburuak. Une honetan ez dugu Dockerfilerik erabiltzen ari.
Irteeratik, hori ikusten dugu paketo Cloud-Native buildpackfuntzionatzen duen OCI irudia sortzeko erabiltzen da. Lehen bezala, Docker irudi gisa zerrendatutako irudia ikus dezakegu komandoa exekutatuz:
Ondoren, Jib plugina exekutatzen dugu Maven komandoa erabiliz aplikazioa eraikitzeko eta edukiontziaren irudia sortzeko. Lehen bezala, hemen ez dugu Dockerfilerik erabiltzen ari:
Goiko Maven komandoa exekutatu ondoren, irteera hau lortuko dugu:
[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
Irteerak erakusten du edukiontziaren irudia sortu eta erregistroan jarri dela.
Irudi optimizatuak sortzeko motibazioak eta metodoak
Bi arrazoi nagusi ditugu optimizatzeko:
produktibitatea: Edukiontzien orkestrazio sistema batean, edukiontzi-irudi bat irudi-erregistrotik ateratzen da edukiontzi-motorra exekutatzen duen ostalarira. Prozesu honi plangintza deitzen zaio. Erregistrotik irudi handiak ateratzeak edukiontzien orkestrazio sistemetan programazio denbora luzeak eta CI kanalizazioetan eraikitzeko denbora luzeak eragiten ditu.
ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ: irudi handiek ere ahultasunetarako eremu handia dute.
Docker irudi bat geruza pila batez osatuta dago, bakoitza gure Dockerfileko adierazpen bat adierazten duena. Geruza bakoitzak azpiko geruzaren aldaketen delta adierazten du. Docker-eko irudi bat erregistrotik ateratzen dugunean, geruzetan ateratzen da eta ostalarian gordetzen da.
Spring Boot erabilerak "pote lodi" barruan bilketa formatu lehenetsi gisa. JAR lodi bati begiratzen diogunean, aplikazioa JAR osoaren zati oso txikia dela ikusten dugu. Hau da gehien aldatzen den zatia. Gainerakoa Spring Framework menpekotasunek osatzen dute.
Optimizazio formula aplikazioa Spring Framework menpekotasunetatik bereizitako maila batean isolatzean oinarritzen da.
JAR fitxategi lodiaren zatirik handiena osatzen duen mendekotasun-geruza behin bakarrik deskargatzen da eta sistema ostalarian gordetzen da.
Aplikazioaren geruza fin bat bakarrik ateratzen da aplikazioen eguneratzeetan eta edukiontzien programazioan. diagrama honetan agertzen den bezala:
Hurrengo ataletan, Spring Boot aplikazio baterako irudi optimizatu hauek nola sortu ikusiko dugu.
Spring Boot aplikazio baterako edukiontzi irudi optimizatua eraikitzea Buildpack-ekin
Spring Boot 2.3-k geruzak onartzen ditu JAR fitxategi lodi baten zatiak geruza bereizietan ateraz. Geruzak egiteko funtzioa lehenespenez desgaituta dago eta esplizituki gaituta egon behar da Spring Boot Maven plugina erabiliz:
Konfigurazio hau erabiliko dugu gure edukiontziaren irudia eraikitzeko lehenengo Buildpack-ekin eta gero Docker-ekin hurrengo ataletan.
Goazen korrika build-imageMaven helburua edukiontzi irudi bat sortzeko:
mvn spring-boot:build-image
Dive exekutatzen badugu emaitzako irudiko geruzak ikusteko, aplikazioaren geruza (gorriz inguratuta) askoz txikiagoa dela kilobyte barrutian ikusiko dugu JAR formatu lodia erabiliz lortu dugunarekin alderatuta:
Spring Boot aplikazio baterako edukiontzi irudi optimizatua eraikitzea Docker-ekin
Maven edo Gradle plugin bat erabili beharrean, geruzadun Docker JAR irudi bat ere sor dezakegu Docker fitxategi batekin.
Docker erabiltzen dugunean, bi urrats gehiago eman behar ditugu geruzak ateratzeko eta azken irudian kopiatzeko.
Maven-ekin geruzak gaituta eraiki ondoren sortutako JAR-aren edukiak itxura hau izango du:
Irteerak izeneko JAR gehigarri bat erakusten du spring-boot-jarmode-layertoolsΠΈ layersfle.idxfitxategia. JAR fitxategi gehigarri honek geruzak egiteko gaitasunak eskaintzen ditu, hurrengo atalean azaltzen den moduan.
Atera menpekotasunak geruza bereizietan
Geruzak gure JAR geruzetatik ikusteko eta ateratzeko, sistemaren propietatea erabiltzen dugu -Djarmode=layertoolshasteko spring-boot-jarmode-layertoolsJAR aplikazioaren ordez:
Komando hau exekutatzeak eskuragarri dauden komando-aukerak dituen irteera bat sortzen du:
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
Irteerak komandoak erakusten ditu list, extractΠΈ helpΡ helplehenetsia izan. Exekutatu dezagun komandoa listaukera:
java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list
Geruza gisa gehi daitezkeen mendekotasunen zerrenda ikusten dugu.
Geruzak lehenespenez:
Geruzaren izena
Edukia
dependencies
bertsioak SNAPSHOT ez duen edozein mendekotasun
spring-boot-loader
JAR Loader Klaseak
snapshot-dependencies
bertsioak SNAPSHOT duen edozein mendekotasuna
application
aplikazio klaseak eta baliabideak
Geruzak urtean definitzen dira layers.idxfitxategia Docker irudian gehitu behar diren ordenan. Geruza hauek cachean gordetzen dira ostalarian lehen eskuraketaren ondoren, ez direlako aldatzen. Aplikazio-geruza eguneratua soilik deskargatzen da ostalarira, eta hori azkarragoa da tamaina murriztua dela eta .
Irudi bat eraikitzea geruza bereizietan ateratako mendekotasunak dituena
Azken irudia bi urratsetan eraikiko dugu izeneko metodoa erabiliz etapa anitzeko muntaia . Lehenengo urratsean mendekotasunak aterako ditugu eta bigarren urratsean ateratako mendekotasunak azkenera kopiatuko ditugu.
Aldatu dezagun gure Dockerfile etapa anitzeko eraikuntza baterako:
# 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"]
Konfigurazio hau aparteko fitxategi batean gordetzen dugu - Dockerfile2.
Docker irudia eraikitzen dugu komandoa erabiliz:
docker build -f Dockerfile2 -t usersignup:v1 .
Komando hau exekutatu ondoren, irteera hau lortuko dugu:
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
Ikus dezakegu Docker irudia irudi ID batekin sortu eta gero etiketatuta dagoela.
Azkenik, Dive komandoa lehen bezala exekutatzen dugu sortutako Docker irudiaren barruko geruzak egiaztatzeko. Irudi ID edo etiketa bat eman dezakegu Dive komandoaren sarrera gisa:
dive userssignup:v1
Irteeran ikus dezakezun bezala, aplikazioa duen geruza 11 KB baino ez da orain eta mendekotasunak geruza bereizietan gordetzen dira.
Atera barne-menpekotasunak geruza bereizietan
Aplikazio-geruzaren tamaina gehiago murriztu dezakegu gure menpekotasun pertsonalizatuetako edozein geruza bereizi batean ateraz, aplikazioarekin ontziratu beharrean, deklaratuz. ymlizeneko antzeko fitxategia layers.idx:
Fitxategi honetan layers.idxizeneko menpekotasun pertsonalizatu bat gehitu dugu, io.myorgbiltegi partekatutik berreskuratutako erakunde-menpekotasunak dituena.
Irteera
Artikulu honetan, Cloud-Native Buildpacks erabiltzea aztertu dugu edukiontzi-irudia zuzenean iturburutik eraikitzeko. Hau Docker erabiltzearen alternatiba bat da edukiontzi-irudia ohiko moduan sortzeko: lehenik eta behin, JAR fitxategi exekutagarri lodi bat sortzen da eta, ondoren, edukiontzi-irudi batean paketatzen da Dockerfileko argibideak zehaztuz.
Gure edukiontzia optimizatzea ere aztertu dugu, ostalarian cachean gordetzen diren geruza bereizietan mendekotasunak ateratzen dituen geruza-funtzio bat sartuz eta edukiontziaren exekuzio-motorretan programazio garaian aplikazio geruza fin bat kargatzen da.
Artikuluan erabilitako iturburu-kode guztia helbidean aurki dezakezu Github .
Komando Erreferentzia
Hona hemen artikulu honetan erabili ditugun komandoen laburpena erreferentzia azkar bat izateko.
Testuinguruaren garbiketa:
docker system prune -a
Edukiontzi-irudia eraikitzea Dockerfile batekin:
docker build -f <Docker file name> -t <tag> .
Eraiki edukiontziaren irudia iturburutik (Dockerfile gabe):
mvn spring-boot:build-image
Ikusi menpekotasun-geruzak. Aplikazio jar fitxategia eraiki aurretik, ziurtatu geruzak egiteko funtzioa gaituta dagoela spring-boot-maven-plugin-en:
java -Djarmode=layertools -jar application.jar list
Atera menpekotasun geruzak. Aplikazio jar fitxategia eraiki aurretik, ziurtatu geruzak egiteko funtzioa gaituta dagoela spring-boot-maven-plugin-en: