Byggja fínstilltar Docker myndir fyrir Spring Boot forrit

Gámar eru orðnir ákjósanlegasta leiðin til að pakka inn forriti með öllum hugbúnaði og stýrikerfi sem er háð því og afhenda þau síðan í mismunandi umhverfi.

Þessi grein fjallar um mismunandi leiðir til að geyma Spring Boot forrit:

  • búa til Docker mynd með Docker skrá,
  • búa til OCI mynd frá uppruna með því að nota Cloud-Native Buildpack,
  • og fínstillingu myndar í keyrslu með því að aðgreina hluta af JAR í mismunandi lög með því að nota marglaga verkfæri.

 Dæmi um kóða

Þessi grein fylgir dæmi um vinnukóða á GitHub .

Hugtök gáma

Við byrjum á gámahugtökum sem notuð eru í greininni:

  • Gámamynd: skrá af ákveðnu sniði. Við munum breyta forritinu okkar í gámamynd með því að keyra byggingartólið.
  • ílát: Keyranlegt tilvik af gámamyndinni.
  • Gámavél: Púkaferlið sem ber ábyrgð á að keyra ílátið.
  • Gámagestgjafi: Hýsingartölvan sem gámavélin keyrir á.
  • Gámaskrá: Almenn staðsetning sem notuð er til að birta og dreifa gámamyndinni.
  • OCI staðallOpen Container Initiative (OCI) er létt, opið stjórnskipulag sem er myndað innan Linux Foundation. OCI Image Specification skilgreinir iðnaðarstaðla fyrir gámamynd og keyrslusnið til að tryggja að allar gámavélar geti keyrt gámamyndir sem búnar eru til með hvaða smíðaverkfæri sem er.

Til að geyma forrit, vefjum við umsókn okkar inn í gámamynd og birtum myndina í sameiginlegri skráningu. Gámakeyrslan sækir þessa mynd úr skránni, pakkar henni upp og keyrir forritið inni í henni.

Útgáfa 2.3 af Spring Boot veitir viðbætur til að búa til OCI myndir.

Docker er algengasta gámaútfærslan og við notum Docker í dæmunum okkar, þannig að allar síðari gámavísanir í þessari grein vísa til Docker.

Byggja gámamynd á hefðbundinn hátt

Það er mjög auðvelt að búa til Docker myndir fyrir Spring Boot forrit með því að bæta nokkrum leiðbeiningum við Docker skrána.

Við búum fyrst til keyranlega JAR skrá og, sem hluti af Docker skráarleiðbeiningunum, afritum keyrslu JAR skrána ofan á JRE grunnmyndina eftir að hafa beitt nauðsynlegum stillingum.

Við skulum búa til vorforritið okkar á Spring Initializr með ósjálfstæði weblombokи actuator. Við erum líka að bæta við hvíldarstýringu til að útvega API með GETaðferð.

Að búa til Dockerfile

Við geymum síðan þetta forrit með því að bæta við Dockerfile:

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

Docker skráin okkar inniheldur grunnmynd frá adoptopenjdk, ofan á sem við afritum JAR skrána okkar og opnum síðan gáttina, 8080sem mun hlusta eftir beiðnum.

Að byggja upp forritið

Fyrst þarftu að búa til forrit með Maven eða Gradle. Hér notum við Maven:

mvn clean package

Þetta býr til keyranlega JAR skrá fyrir forritið. Við þurfum að breyta þessu keyranlega JAR í Docker mynd til að keyra á Docker vélinni.

Að búa til gámamynd

Við setjum síðan þessa keyrslu JAR skrá inn í Docker myndina með því að keyra skipunina docker buildúr rótarskrá verkefnisins sem inniheldur Dockerfile sem var búin til áður:

docker build  -t usersignup:v1 .

Við getum séð myndina okkar á listanum með því að nota skipunina:

docker images 

Framleiðsla ofangreindrar skipunar inniheldur myndina okkar usersignupásamt grunnmyndinni, adoptopenjdktilgreint í Docker skránni okkar.

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

Skoðaðu lög inni í gámamynd

Við skulum skoða lagastaflann inni í myndinni. Við munum nota инструмент  dífa til að skoða þessi lög:

dive usersignup:v1

Hér er hluti af úttakinu frá Dive skipuninni: 

Byggja fínstilltar Docker myndir fyrir Spring Boot forrit

Eins og við sjáum er umsóknarlagið umtalsverðan hluta myndstærðarinnar. Við viljum minnka stærð þessa lags í eftirfarandi köflum sem hluti af hagræðingu okkar.

Að búa til gámamynd með því að nota Buildpack

Samsetningarpakkar (Byggingapakkar) er almennt hugtak sem notað er af ýmsum kerfum sem þjónustu (PAAS) til að búa til gámamynd úr frumkóða. Það var hleypt af stokkunum af Heroku árið 2011 og hefur síðan verið samþykkt af Cloud Foundry, Google App Engine, Gitlab, Knative og nokkrum öðrum.

Byggja fínstilltar Docker myndir fyrir Spring Boot forrit

Kosturinn við skýjasmíðapakka

Einn helsti kosturinn við að nota Buildpack til að búa til myndir er sá Hægt er að stjórna breytingum á myndstillingum miðlægt (byggir) og dreifa þeim í öll forrit sem nota byggir.

Byggingarpakkarnir voru þétt tengdir við pallinn. Cloud-Native Buildpacks veita stöðlun á milli kerfa með því að styðja OCI myndsniðið, sem tryggir að hægt sé að keyra myndina af Docker vélinni.

Að nota Spring Boot viðbótina

Spring Boot viðbótin byggir OCI myndir frá uppruna með því að nota Buildpack. Myndir eru búnar til með því að nota bootBuildImageverkefni (Gradle) eða spring-boot:build-imageskotmörk (Maven) og staðbundna Docker uppsetningu.

Við getum sérsniðið nafn myndarinnar sem þarf til að ýta á Docker skrásetninguna með því að tilgreina nafnið í 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>

Við skulum nota Maven til að gera það build-imagemarkmið við að búa til forrit og búa til gámamynd. Við erum ekki að nota neinar Dockerfiles eins og er.

mvn spring-boot:build-image

Útkoman verður eitthvað á þessa leið:

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

Af úttakinu sjáum við það paketo Cloud-Native buildpacknotað til að búa til virka OCI mynd. Eins og áður getum við séð myndina skráða sem Docker mynd með því að keyra skipunina:

docker images 

Ályktun:

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

Að búa til gámamynd með því að nota Jib

Jib er myndsköpunarviðbót frá Google sem býður upp á aðra aðferð til að búa til gámamynd úr frumkóða.

Stillir jib-maven-pluginí pom.xml:

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

Næst keyrum við Jib viðbótina með Maven skipuninni til að smíða forritið og búa til gámamynd. Eins og áður erum við ekki að nota neinar Docker skrár hér:

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

Eftir að hafa framkvæmt ofangreinda Maven skipun fáum við eftirfarandi úttak:

[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

Úttakið sýnir að gámamyndin hefur verið búin til og sett í skrána.

Hvatar og tækni til að búa til fínstilltar myndir

Við höfum tvær meginástæður fyrir hagræðingu:

  • Framleiðni: Í gámaskipunarkerfi er gámamynd sótt úr myndaskránni til hýsilsins sem keyrir gámavélina. Þetta ferli er kallað áætlanagerð. Að draga stórar myndir úr skránni hefur í för með sér langan tímasetningartíma í gámaskipunarkerfum og langan byggingartíma í CI leiðslum.
  • öryggi: Stærri myndir hafa einnig stærra svæði fyrir varnarleysi.

Docker mynd samanstendur af stafla af lögum, sem hvert um sig táknar leiðbeiningar í Dockerfile okkar. Hvert lag táknar delta af breytingum á undirliggjandi laginu. Þegar við tökum Docker mynd úr skránni er hún dregin í lögum og sett í skyndiminni á hýsilinn.

Spring Boot notar "fat JAR" í sem sjálfgefið umbúðasnið. Þegar við skoðum þykka JAR sjáum við að forritið er mjög lítill hluti af öllu JAR. Þetta er sá hluti sem breytist oftast. Afgangurinn samanstendur af Spring Framework ósjálfstæðum.

Hagræðingarformúlan snýst um að einangra forritið á aðskildu stigi frá Spring Framework ósjálfstæði.

Ósjálfstæðislagið, sem myndar megnið af þykku JAR skránni, er aðeins hlaðið niður einu sinni og í skyndiminni á hýsingarkerfinu.

Aðeins þunnt lag af forritinu er dregið við forritauppfærslur og gámaáætlun. eins og sýnt er á þessari skýringarmynd:

Byggja fínstilltar Docker myndir fyrir Spring Boot forrit

Í eftirfarandi köflum munum við skoða hvernig á að búa til þessar fínstilltu myndir fyrir Spring Boot forrit.

Að búa til fínstillta gámamynd fyrir Spring Boot forrit með því að nota Buildpack

Spring Boot 2.3 styður lagskiptingu með því að draga hluta af þykkri JAR skrá í aðskilin lög. Lagaeiginleikinn er sjálfgefið óvirkur og verður að vera sérstaklega virkur með því að nota Spring Boot Maven viðbótina:

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

Við munum nota þessa stillingu til að byggja gámamyndina okkar fyrst með Buildpack og síðan með Docker í eftirfarandi köflum.

Við skulum ræsa build-imageMaven markmið til að búa til gámamynd:

mvn spring-boot:build-image

Ef við keyrum Dive til að sjá lögin á myndinni sem myndast, getum við séð að forritalagið (útlistað með rauðu) er mun minna á kílóbætabilinu samanborið við það sem við fengum með því að nota þykka JAR sniðið:

Byggja fínstilltar Docker myndir fyrir Spring Boot forrit

Að búa til fínstillta gámamynd fyrir vorræsiforrit með því að nota Docker

Í stað þess að nota Maven eða Gradle viðbót, getum við líka búið til lagskipt Docker JAR mynd með Docker skrá.

Þegar við notum Docker þurfum við að framkvæma tvö viðbótarskref til að draga út lögin og afrita þau inn í lokamyndina.

Innihald JAR sem myndast eftir byggingu með Maven með lagskipting virkt mun líta svona út:

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

Úttakið sýnir JAR til viðbótar sem heitir spring-boot-jarmode-layertoolsи layersfle.idxskrá. Þessi viðbótar JAR skrá býður upp á lagskipt vinnslumöguleika, eins og lýst er í næsta kafla.

Að draga út ósjálfstæði á einstökum lögum

Til að skoða og draga lög úr lagskiptu JAR okkar notum við kerfiseiginleikann -Djarmode=layertoolstil að byrja með spring-boot-jarmode-layertoolsJAR í stað umsóknar:

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

Að keyra þessa skipun framleiðir úttak sem inniheldur tiltæka skipanavalkosti:

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

Úttakið sýnir skipanirnar listextractи helpс helpvera sjálfgefið. Við skulum keyra skipunina með listvalmöguleiki:

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

Við sjáum lista yfir ósjálfstæði sem hægt er að bæta við sem lögum.

Sjálfgefin lög:

Nafn lags

efni

dependencies

hvers kyns ósjálfstæði þar sem útgáfan inniheldur ekki SNAPSHOT

spring-boot-loader

JAR Loader flokkar

snapshot-dependencies

hvers kyns ósjálfstæði þar sem útgáfan inniheldur SNAPSHOT

application

umsóknarflokkar og úrræði

Lög eru skilgreind í layers.idxskrá í þeirri röð sem þeim ætti að bæta við Docker myndina. Þessi lög eru í skyndiminni í hýsilinn eftir fyrstu endurheimt vegna þess að þau breytast ekki. Aðeins uppfærða forritalagið er hlaðið niður á gestgjafann, sem er hraðari vegna minni stærðar .

Byggja upp mynd með ósjálfstæði dregin út í aðskilin lög

Við munum byggja lokamyndina í tveimur áföngum með aðferð sem kallast fjölþrepa samsetning . Í fyrsta skrefi munum við draga út ósjálfstæðin og í öðru skrefi munum við afrita útdráttarháðirnar í lokamyndina.

Við skulum breyta Dockerfile okkar fyrir fjölþrepa byggingu:

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

Við vistum þessa stillingu í sérstakri skrá - Dockerfile2.

Við byggjum Docker myndina með því að nota skipunina:

docker build -f Dockerfile2 -t usersignup:v1 .

Eftir að hafa keyrt þessa skipun fáum við eftirfarandi úttak:

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

Við getum séð að Docker mynd er búin til með myndauðkenni og síðan merkt.

Að lokum keyrum við Dive skipunina eins og áður til að skoða lögin inni í myndaðri Docker myndinni. Við getum veitt myndauðkenni eða merki sem inntak í köfunarskipunina:

dive userssignup:v1

Eins og þú sérð í úttakinu er lagið sem inniheldur forritið nú aðeins 11 KB og ósjálfstæði eru vistuð í aðskildum lögum. 

Byggja fínstilltar Docker myndir fyrir Spring Boot forrit

Að draga út innri ósjálfstæði á einstökum lögum

Við getum minnkað enn frekar stærð forritastigsins með því að draga eitthvað af sérsniðnum ósjálfstæðum okkar í sérstakt flokk í stað þess að pakka þeim með forritinu með því að lýsa þeim í ymlsvipuð skrá nefnd 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/"

Í þessari skrá layers.idxvið höfum bætt við sérsniðinni ósjálfstæði sem heitir, io.myorgsem inniheldur ósjálfstæði fyrirtækis sem eru sótt úr sameiginlegri geymslu.

Output

Í þessari grein skoðuðum við notkun Cloud-Native Buildpacks til að búa til gámamynd beint úr frumkóða. Þetta er valkostur við að nota Docker til að búa til gámamynd á venjulegan hátt: fyrst að búa til þykka keyranlega JAR skrá og pakka henni síðan inn í gámamynd með því að tilgreina leiðbeiningar í Docker skránni.

Við skoðuðum líka að fínstilla ílátið okkar með því að virkja lagskiptingareiginleika sem dregur ósjálfstæði í aðskilin lög sem eru í skyndiminni á hýsilinn og þunnt lag af forritinu er hlaðið á tímasetningartíma í framkvæmdarvélum ílátsins.

Þú getur fundið allan frumkóðann sem notaður er í greininni á GitHub .

Skipunartilvísun

Hér er stutt yfirlit yfir skipanirnar sem við notuðum í þessari grein.

Samhengishreinsun:

docker system prune -a

Að búa til gámamynd með því að nota Docker skrá:

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

Við smíðum gámamyndina úr frumkóðanum (án Dockerfile):

mvn spring-boot:build-image

Skoða ósjálfstæðislög. Áður en JAR-skrá forritsins er smíðað skaltu ganga úr skugga um að lagskiptingareiginleikinn sé virkur í spring-boot-maven-plugin:

java -Djarmode=layertools -jar application.jar list

Að draga út ósjálfstæðislög. Áður en JAR-skrá forritsins er smíðað skaltu ganga úr skugga um að lagskiptingareiginleikinn sé virkur í spring-boot-maven-plugin:

 java -Djarmode=layertools -jar application.jar extract

Skoðaðu lista yfir gámamyndir

docker images

Skoðaðu til vinstri inni í gámamyndinni (vertu viss um að köfunartólið sé uppsett):

dive <image ID or image tag>

Heimild: www.habr.com