ProHoster > Blog > Uprava > Ustvarjanje optimiziranih slik Docker za spomladansko zagonsko aplikacijo
Ustvarjanje optimiziranih slik Docker za spomladansko zagonsko aplikacijo
Vsebniki so postali prednostno sredstvo za pakiranje aplikacije z vso njeno programsko opremo in odvisnostmi operacijskega sistema ter njihovo nato dostavo v različna okolja.
Ta članek pokriva različne načine za shranjevanje aplikacije Spring Boot:
ustvarjanje slike Docker z uporabo datoteke Docker,
ustvarjanje slike OCI iz vira z uporabo Cloud-Native Buildpack,
in optimizacijo slike med izvajanjem z ločevanjem delov JAR v različne plasti z uporabo večplastnih orodij.
Vzorčna koda
Ta članek spremlja primer delujoče kode na GitHubu .
Kontejnerska terminologija
Začeli bomo s terminologijo vsebnika, uporabljeno v članku:
Slika vsebnika: datoteka določenega formata. Našo aplikacijo bomo pretvorili v sliko vsebnika z zagonom orodja za gradnjo.
posoda: Izvedljiv primerek slike vsebnika.
Kontejnerski motor: demonski proces, odgovoren za izvajanje vsebnika.
Gostitelj vsebnika: gostiteljski računalnik, na katerem teče motor vsebnika.
Register zabojnikov: splošna lokacija, ki se uporablja za objavo in distribucijo slike vsebnika.
OCI standard: Pobuda za odprti zabojnik (OCI) je lahka, odprta struktura upravljanja, oblikovana znotraj Linux Foundation. Specifikacija slike OCI določa industrijske standarde za formate slike vsebnika in izvajalnega okolja, da zagotovi, da lahko vsi motorji vsebnika izvajajo slike vsebnika, ustvarjene s katerim koli orodjem za gradnjo.
Za shranjevanje aplikacije v vsebnik zavijemo našo aplikacijo v sliko vsebnika in to sliko objavimo v skupnem registru. Izvajalno okolje vsebnika pridobi to sliko iz registra, jo razpakira in zažene aplikacijo v njej.
Različica 2.3 programa Spring Boot ponuja vtičnike za ustvarjanje slik OCI.
Lučki delavec je najpogosteje uporabljena izvedba vsebnika, v naših primerih pa uporabljamo Docker, zato se bodo vse nadaljnje reference vsebnika v tem članku nanašale na Docker.
Gradnja slike vsebnika na tradicionalen način
Ustvarjanje slik Docker za aplikacije Spring Boot je zelo preprosto z dodajanjem nekaj navodil v datoteko Docker.
Najprej ustvarimo izvedljivo datoteko JAR in kot del navodil za datoteko Docker kopiramo izvršljivo datoteko JAR na vrh osnovne slike JRE, potem ko uporabimo potrebne nastavitve.
Ustvarimo našo aplikacijo Spring on Inicializacija pomladi z odvisnostmi web, lombokи actuator. Dodajamo tudi krmilnik za počitek, ki zagotavlja API GETmetoda.
Ustvarjanje datoteke Docker
Nato to aplikacijo pospravimo v kontejner z dodajanjem Dockerfile:
Naša datoteka Docker vsebuje osnovno sliko iz adoptopenjdk, na katerega prekopiramo našo datoteko JAR in nato odpremo vrata, 8080ki bo poslušal zahteve.
Gradnja aplikacije
Najprej morate ustvariti aplikacijo z Maven ali Gradle. Tukaj uporabljamo Maven:
mvn clean package
To ustvari izvršljivo datoteko JAR za aplikacijo. To izvršljivo datoteko JAR moramo pretvoriti v sliko Docker, da se bo izvajala na motorju Docker.
Ustvarjanje slike vsebnika
To izvršljivo datoteko JAR nato vstavimo v sliko Dockerja tako, da zaženemo ukaz docker buildiz korenskega imenika projekta, ki vsebuje prej ustvarjeno datoteko Docker:
docker build -t usersignup:v1 .
Našo sliko lahko vidimo na seznamu z ukazom:
docker images
Izhod zgornjega ukaza vključuje našo sliko usersignupskupaj z osnovno sliko, adoptopenjdkdoločeno v naši datoteki Docker.
REPOSITORY TAG SIZE
usersignup v1 249MB
adoptopenjdk 11-jre-hotspot 229MB
Oglejte si plasti znotraj slike vsebnika
Poglejmo kup plasti znotraj slike. Bomo uporabili Orodje potapljanje za ogled teh plasti:
dive usersignup:v1
Tukaj je del izhoda ukaza Dive:
Kot lahko vidimo, sloj aplikacije predstavlja pomemben del velikosti slike. V naslednjih razdelkih želimo zmanjšati velikost te plasti kot del naše optimizacije.
Ustvarjanje slike vsebnika z uporabo Buildpack
Montažni paketi (Buildpacks) je splošni izraz, ki ga uporabljajo različne ponudbe platforme kot storitve (PAAS) za ustvarjanje slike vsebnika iz izvorne kode. Leta 2011 ga je lansiral Heroku, od takrat pa so ga sprejeli Cloud Foundry, Google App Engine, Gitlab, Knative in številni drugi.
Prednost paketov za gradnjo v oblaku
Ena od glavnih prednosti uporabe Buildpacka za ustvarjanje slik je ta Spremembe konfiguracije slike je mogoče upravljati centralno (builder) in jih razširiti na vse aplikacije z graditeljem.
Gradbeni paketi so bili tesno povezani s platformo. Cloud-Native Buildpacks zagotavljajo standardizacijo na različnih platformah s podporo formata slike OCI, ki zagotavlja, da lahko sliko izvaja mehanizem Docker.
Uporaba vtičnika Spring Boot
Vtičnik Spring Boot gradi slike OCI iz vira z uporabo Buildpack. Slike so ustvarjene z uporabo bootBuildImageopravil (Gradle) oz spring-boot:build-imagecilji (Maven) in lokalna namestitev Dockerja.
Prilagodimo lahko ime slike, ki jo je treba potisniti v register Docker, tako da vnesemo ime image tag:
Iz izhoda to vidimo paketo Cloud-Native buildpackuporablja za ustvarjanje delujoče slike OCI. Tako kot prej lahko vidimo sliko, navedeno kot Dockerjeva slika, tako da zaženemo ukaz:
Po izvedbi zgornjega ukaza Maven dobimo naslednji rezultat:
[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
Izhod kaže, da je bila slika vsebnika ustvarjena in postavljena v register.
Motivacije in tehnike za ustvarjanje optimiziranih slik
Za optimizacijo imamo dva glavna razloga:
Produktivnost: V sistemu za orkestracijo vsebnika se slika vsebnika pridobi iz registra slik v gostitelja, ki izvaja motor vsebnika. Ta proces se imenuje načrtovanje. Vlečenje velikih slik iz registra povzroči dolge čase načrtovanja v sistemih za orkestracijo vsebnikov in dolge čase gradnje v cevovodih CI.
varnost: Večje slike imajo tudi večjo površino za ranljivosti.
Slika Docker je sestavljena iz niza plasti, od katerih vsaka predstavlja navodilo v naši datoteki Docker. Vsaka plast predstavlja delto sprememb v spodnji plasti. Ko potegnemo sliko Dockerja iz registra, se povleče v plasteh in shrani v predpomnilnik na gostitelju.
Spring Boot uporablja "fat JAR" v kot privzeti format pakiranja. Ko pogledamo debel JAR, vidimo, da aplikacija predstavlja zelo majhen del celotnega JAR-a. To je del, ki se najpogosteje spreminja. Preostanek sestavljajo odvisnosti Spring Framework.
Formula optimizacije se osredotoča na izolacijo aplikacije na ločeni ravni od odvisnosti Spring Framework.
Plast odvisnosti, ki tvori večji del debele datoteke JAR, se prenese samo enkrat in shrani v predpomnilnik v gostiteljskem sistemu.
Med posodobitvami aplikacij in razporejanjem vsebnika se potegne le tanka plast aplikacije. kot je prikazano v tem diagramu:
V naslednjih razdelkih si bomo ogledali, kako ustvariti te optimizirane slike za aplikacijo Spring Boot.
Ustvarjanje optimizirane slike vsebnika za spomladansko zagonsko aplikacijo z uporabo Buildpack
Spring Boot 2.3 podpira plastenje z ekstrakcijo delov debele datoteke JAR v ločene plasti. Funkcija slojevanja je privzeto onemogočena in jo je treba izrecno omogočiti z uporabo vtičnika Spring Boot Maven:
To konfiguracijo bomo uporabili za izdelavo naše slike vsebnika najprej z Buildpackom in nato z Dockerjem v naslednjih razdelkih.
Zaženimo build-imageCilj Maven za ustvarjanje slike vsebnika:
mvn spring-boot:build-image
Če zaženemo Dive, da vidimo plasti na dobljeni sliki, lahko vidimo, da je aplikacijska plast (obrobljena z rdečo) veliko manjša v obsegu kilobajtov v primerjavi s tistim, kar smo dobili z debelim formatom JAR:
Ustvarjanje optimizirane slike vsebnika za spomladansko zagonsko aplikacijo z uporabo Dockerja
Namesto uporabe vtičnika Maven ali Gradle lahko ustvarimo večplastno sliko Docker JAR z datoteko Docker.
Ko uporabljamo Docker, moramo izvesti dva dodatna koraka, da ekstrahiramo plasti in jih kopiramo v končno sliko.
Vsebina dobljene datoteke JAR po gradnji z uporabo programa Maven z omogočenim slojevanjem bo videti takole:
Izhod prikazuje dodatno JAR z imenom spring-boot-jarmode-layertoolsи layersfle.idxmapa. Ta dodatna datoteka JAR zagotavlja zmožnosti večplastne obdelave, kot je opisano v naslednjem razdelku.
Ekstrahiranje odvisnosti na posameznih slojih
Za ogled in ekstrahiranje slojev iz večplastnega JAR-ja uporabljamo sistemsko lastnost -Djarmode=layertoolsza začetek spring-boot-jarmode-layertoolsJAR namesto aplikacije:
Zagon tega ukaza ustvari izpis, ki vsebuje razpoložljive ukazne možnosti:
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
Izhod prikazuje ukaze list, extractи helpс helpbiti privzeto. Zaženimo ukaz z listmožnost:
java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list
Vidimo seznam odvisnosti, ki jih je mogoče dodati kot plasti.
Privzeti sloji:
Ime sloja
Vsebina
dependencies
katera koli odvisnost, katere različica ne vsebuje SNAPSHOT
spring-boot-loader
Razredi nalagalnika JAR
snapshot-dependencies
katera koli odvisnost, katere različica vsebuje SNAPSHOT
application
aplikacijski razredi in viri
Plasti so definirane v layers.idxdatoteko v vrstnem redu, kot naj bodo dodani sliki Docker. Ti sloji so predpomnjeni v gostitelju po prvem priklicu, ker se ne spremenijo. Na gostitelja se prenese samo posodobljena aplikacijska plast, ki je hitrejša zaradi zmanjšane velikosti .
Gradnja slike z odvisnostmi, ekstrahiranimi v ločene plasti
Končno sliko bomo zgradili v dveh fazah z metodo imenovano večstopenjska montaža . V prvem koraku bomo ekstrahirali odvisnosti, v drugem koraku pa kopirali ekstrahirane odvisnosti v končno sliko.
Spremenimo našo datoteko Dockerfile za večstopenjsko gradnjo:
# 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"]
To konfiguracijo shranimo v ločeno datoteko - Dockerfile2.
Sliko Docker zgradimo z ukazom:
docker build -f Dockerfile2 -t usersignup:v1 .
Po izvedbi tega ukaza dobimo naslednji rezultat:
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
Vidimo lahko, da je slika Docker ustvarjena z ID-jem slike in nato označena.
Na koncu zaženemo ukaz Dive kot prej, da pregledamo plasti znotraj ustvarjene slike Docker. Kot vhod v ukaz Dive lahko zagotovimo ID slike ali oznako:
dive userssignup:v1
Kot lahko vidite v izhodu, je sloj, ki vsebuje aplikacijo, zdaj velik samo 11 KB, odvisnosti pa so predpomnjene v ločenih slojih.
Izločanje notranjih odvisnosti na posameznih slojih
Velikost ravni aplikacije lahko dodatno zmanjšamo tako, da ekstrahiramo vse naše odvisnosti po meri v ločeno raven, namesto da jih zapakiramo z aplikacijo tako, da jih prijavimo v ymlpodobna datoteka z imenom layers.idx:
V tej datoteki layers.idxdodali smo odvisnost po meri z imenom, io.myorgki vsebuje odvisnosti organizacije, pridobljene iz skupnega repozitorija.
Izhod
V tem članku smo si ogledali uporabo Cloud-Native Buildpacks za izdelavo slike vsebnika neposredno iz izvorne kode. To je alternativa uporabi Dockerja za ustvarjanje slike vsebnika na običajen način: najprej ustvarite debelo izvedljivo datoteko JAR in jo nato zapakirate v sliko vsebnika z določitvijo navodil v datoteki Docker.
Preučili smo tudi optimizacijo našega vsebnika z omogočanjem funkcije razporejanja po plasteh, ki povleče odvisnosti v ločene plasti, ki so predpomnjene na gostitelju, in tanka plast aplikacije se naloži ob času razporejanja v izvajalske mehanizme vsebnika.
Vso izvorno kodo, uporabljeno v članku, najdete na GitHub .
Referenca ukaza
Tukaj je kratek povzetek ukazov, ki smo jih uporabili v tem članku.
Čiščenje konteksta:
docker system prune -a
Ustvarjanje slike vsebnika z uporabo datoteke Docker:
docker build -f <Docker file name> -t <tag> .
Sliko vsebnika zgradimo iz izvorne kode (brez datoteke Dockerfile):
mvn spring-boot:build-image
Oglejte si sloje odvisnosti. Pred gradnjo datoteke JAR aplikacije se prepričajte, da je funkcija razslojevanja omogočena v vtičniku spring-boot-maven-plugin:
java -Djarmode=layertools -jar application.jar list
Ekstrahiranje slojev odvisnosti. Pred gradnjo datoteke JAR aplikacije se prepričajte, da je funkcija razslojevanja omogočena v vtičniku spring-boot-maven-plugin: