Nyiptakeun Gambar Docker Dioptimalkeun pikeun Aplikasi Spring Boot

Wadahna parantos janten cara anu dipikaresep pikeun ngabungkus aplikasi sareng sadaya katergantungan parangkat lunak sareng sistem operasi teras dikirimkeun ka lingkungan anu béda.

Tulisan ieu nyertakeun sababaraha cara pikeun wadahna aplikasi Spring Boot:

  • nyiptakeun gambar Docker nganggo file Docker,
  • nyiptakeun gambar OCI tina sumber nganggo Cloud-Native Buildpack,
  • sarta optimasi gambar ngajalankeun-waktos ku misahkeun bagéan JAR kana lapisan béda ngagunakeun parabot multi-tier.

 Conto Kode

Artikel ieu dipirig ku conto kode gawé dina GitHub .

Terminologi wadahna

Urang mimitian ku terminologi wadah anu dianggo dina tulisan:

  • Gambar wadahna: file tina format husus. Urang bakal ngarobah aplikasi urang kana gambar wadahna ku ngajalankeun alat ngawangun.
  • wadah: Hiji conto laksana tina gambar wadahna.
  • Mesin wadahna: Prosés daemon jawab ngajalankeun wadahna.
  • Host wadahna: Komputer host dimana mesin wadahna jalan.
  • pendaptaran wadahna: Lokasi umum dipaké pikeun nyebarkeun jeung ngadistribusikaeun gambar wadahna.
  • standar OCIOpen Container Initiative (OCI) nyaéta struktur pamaréntahan anu ringan sareng kabuka anu dibentuk dina Yayasan Linux. Spésifikasi Gambar OCI ngahartikeun standar industri pikeun gambar wadahna sareng format runtime pikeun mastikeun yén sadaya mesin wadahna tiasa ngajalankeun gambar wadahna anu diciptakeun ku alat ngawangun.

Pikeun wadahna aplikasi, urang bungkus aplikasi urang dina gambar wadahna sareng nyebarkeun gambar éta kana pendaptaran anu dibagikeun. Wadahna runtime retrieves gambar ieu ti pendaptaran, unpacks eta, sarta ngajalankeun aplikasi di jero eta.

Vérsi 2.3 tina Spring Boot nyadiakeun plugins pikeun nyieun gambar OCI.

Docker nyaéta palaksanaan wadahna anu paling sering dianggo, sareng kami nganggo Docker dina conto kami, janten sadaya rujukan wadahna dina tulisan ieu bakal ngarujuk ka Docker.

Ngawangun gambar wadah ku cara tradisional

Nyiptakeun gambar Docker pikeun aplikasi Spring Boot gampang pisan ku nambihan sababaraha petunjuk kana file Docker.

Urang mimiti nyiptakeun file JAR anu tiasa dieksekusi sareng, salaku bagian tina petunjuk file Docker, nyalin file JAR anu tiasa dieksekusi dina luhureun gambar JRE dasar saatos nerapkeun setélan anu diperyogikeun.

Hayu urang nyieun aplikasi Spring urang on Spring Initializr kalawan kagumantungan weblombokи actuator. Urang ogé nambahkeun controller sésana pikeun nyadiakeun API kalawan GETmétode.

Nyieun Dockerfile

Urang lajeng containerize aplikasi ieu ku nambahkeun Dockerfile:

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

File Docker kami ngandung gambar dasar tina adoptopenjdk, di luhurna urang nyalin file JAR kami teras buka port, 8080nu bakal ngadangukeun requests.

Ngawangun aplikasi

Mimiti anjeun kedah ngadamel aplikasi nganggo Maven atanapi Gradle. Di dieu kami nganggo Maven:

mvn clean package

Ieu nyiptakeun file JAR anu tiasa dieksekusi pikeun aplikasi. Urang kedah ngarobih JAR anu tiasa dieksekusi ieu kana gambar Docker pikeun dijalankeun dina mesin Docker.

Nyieun gambar wadahna

Urang teras nempatkeun file JAR anu tiasa dieksekusi ieu kana gambar Docker ku ngajalankeun paréntahna docker buildtina diréktori akar proyék anu ngandung Dockerfile anu didamel sateuacana:

docker build  -t usersignup:v1 .

Urang tiasa ningali gambar urang dina daptar nganggo paréntah:

docker images 

Kaluaran paréntah di luhur kalebet gambar urang usersignupbareng jeung gambar dasar, adoptopenjdkdieusian dina file Docker kami.

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

Témbongkeun lapisan dina gambar wadahna

Hayu urang tingali tumpukan lapisan di jero gambar. Urang bakal ngagunakeun alat  teuleum pikeun ningali lapisan ieu:

dive usersignup:v1

Ieu bagian tina kaluaran tina paréntah Dive: 

Nyiptakeun Gambar Docker Dioptimalkeun pikeun Aplikasi Spring Boot

Sakumaha anu urang tingali, lapisan aplikasi mangrupikeun bagian anu penting tina ukuran gambar. Kami hoyong ngirangan ukuran lapisan ieu dina bagian di handap ieu salaku bagian tina optimasi kami.

Nyiptakeun gambar wadah nganggo Buildpack

bungkusan Majelis (Buildpacks) nyaéta istilah umum anu digunakeun ku rupa-rupa Panawaran Platform salaku Service (PAAS) pikeun nyiptakeun gambar wadahna tina kode sumber. Diluncurkeun ku Heroku di 2011 sareng parantos diadopsi ku Cloud Foundry, Google App Engine, Gitlab, Knative sareng sababaraha anu sanésna.

Nyiptakeun Gambar Docker Dioptimalkeun pikeun Aplikasi Spring Boot

Kauntungannana pakét ngawangun awan

Salah sahiji kauntungan utama ngagunakeun Buildpack pikeun nyiptakeun gambar nyaéta éta Parobihan konfigurasi gambar tiasa diurus sacara sentral (pembina) sareng disebarkeun ka sadaya aplikasi nganggo pembina.

Bungkusan ngawangun dipasang caket kana platform. Cloud-Native Buildpacks nyayogikeun standarisasi dina platform ku ngadukung format gambar OCI, anu mastikeun yén gambar tiasa dijalankeun ku mesin Docker.

Ngagunakeun plugin Spring Boot

Plugin Spring Boot ngawangun gambar OCI tina sumber nganggo Buildpack. Gambar dijieun ngagunakeun bootBuildImagetugas (Gradle) atawa spring-boot:build-imagetarget (Maven) sareng pamasangan Docker lokal.

Urang tiasa ngaropea nami gambar anu diperyogikeun pikeun nyorong kana pendaptaran Docker ku netepkeun nami dina 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>

Hayu urang nganggo Maven pikeun ngalakukeunana build-imagetujuan pikeun nyieun aplikasi jeung nyieun gambar wadahna. Kami henteu nganggo Dockerfiles dina waktos ayeuna.

mvn spring-boot:build-image

Hasilna bakal sapertos kieu:

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

Tina kaluaran kami ningali éta paketo Cloud-Native buildpackdipaké pikeun nyieun gambar OCI digawé. Sapertos sateuacanna, urang tiasa ningali gambar didaptarkeun salaku gambar Docker ku ngajalankeun paréntah:

docker images 

kacindekan:

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

Nyiptakeun gambar wadahna nganggo Jib

Jib mangrupikeun plugin nyiptakeun gambar ti Google anu nyayogikeun metode alternatif pikeun nyiptakeun gambar wadahna tina kode sumber.

Ngonpigurasikeun jib-maven-plugindina pom.xml:

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

Salajengna, urang ngajalankeun plugin Jib nganggo paréntah Maven pikeun ngawangun aplikasi sareng nyiptakeun gambar wadahna. Sapertos sateuacanna, kami henteu nganggo file Docker di dieu:

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

Saatos ngalaksanakeun paréntah Maven di luhur, urang nampi kaluaran ieu:

[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

Kaluaran nunjukkeun yén gambar wadahna parantos didamel sareng disimpen dina pendaptaran.

Motivasi sareng téknik pikeun nyiptakeun gambar anu dioptimalkeun

Kami gaduh dua alesan utama pikeun optimasi:

  • kakuwatan keur ngasilkeun: Dina sistem orkestrasi wadahna, gambar wadahna dicandak tina pendaptaran gambar ka host anu ngajalankeun mesin wadahna. Prosés ieu disebut perencanaan. Narik gambar ageung tina pendaptaran nyababkeun waktos jadwal anu panjang dina sistem orkestrasi wadahna sareng waktos ngawangun panjang dina pipa CI.
  • kasalametan: Gambar anu langkung ageung ogé gaduh daérah anu langkung ageung pikeun kerentanan.

Gambar Docker diwangun ku tumpukan lapisan, anu masing-masing ngagambarkeun instruksi dina Dockerfile kami. Unggal lapisan ngagambarkeun délta tina parobahan dina lapisan kaayaan. Nalika urang narik gambar Docker tina pendaptaran, éta ditarik dina lapisan sareng sindangan dina host.

Spring Boot ngagunakeun "JAR gajih" dina salaku format bungkusan standar. Lamun urang tingali dina jar kandel, urang tingali yen aplikasi nu nyieun hiji porsi leutik pisan tina sakabéh jar. Ieu mangrupikeun bagian anu paling sering robih. Sésana diwangun ku kagumantungan Spring Framework.

Rumus optimasi dipuseurkeun pikeun ngasingkeun aplikasi dina tingkat anu misah tina katergantungan Spring Framework.

Lapisan kagumantungan, anu ngabentuk seueur file JAR kandel, ngan ukur diunduh sakali sareng disimpen dina sistem host.

Ngan hiji lapisan ipis tina aplikasi ditarik salila apdet aplikasi tur scheduling wadahna. sakumaha ditémbongkeun dina diagram ieu:

Nyiptakeun Gambar Docker Dioptimalkeun pikeun Aplikasi Spring Boot

Dina bagian di handap ieu, urang bakal ningali kumaha cara nyiptakeun gambar anu dioptimalkeun ieu pikeun aplikasi Spring Boot.

Nyiptakeun Gambar Wadah anu Dioptimalkeun pikeun Aplikasi Spring Boot Nganggo Buildpack

Spring Boot 2.3 ngarojong layering ku extracting bagian tina file JAR kandel kana lapisan misah. Fitur layering ditumpurkeun sacara standar sareng kedah diaktipkeun sacara eksplisit nganggo plugin Spring Boot Maven:

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

Urang bakal ngagunakeun konfigurasi ieu pikeun ngawangun gambar wadahna urang mimiti kalawan Buildpack lajeng kalawan Docker dina bagian handap.

Hayu urang ngajalankeun build-imageTarget Maven pikeun nyiptakeun gambar wadahna:

mvn spring-boot:build-image

Upami urang ngajalankeun Dive pikeun ningali lapisan dina gambar anu dihasilkeun, urang tiasa ningali yén lapisan aplikasi (digariskeun beureum) langkung alit dina kisaran kilobyte dibandingkeun sareng naon anu urang kéngingkeun nganggo format JAR gajih:

Nyiptakeun Gambar Docker Dioptimalkeun pikeun Aplikasi Spring Boot

Nyiptakeun Gambar Wadah Dioptimalkeun pikeun Aplikasi Spring Boot Nganggo Docker

Gantina nganggo plugin Maven atanapi Gradle, urang ogé tiasa nyiptakeun gambar Docker JAR berlapis sareng file Docker.

Nalika kami nganggo Docker, urang kedah ngalakukeun dua léngkah tambahan pikeun nimba lapisan sareng nyalin kana gambar ahir.

Eusi JAR anu dihasilkeun saatos ngawangun nganggo Maven kalayan lapisan diaktipkeun bakal katingali sapertos kieu:

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

output nembongkeun hiji JAR tambahan ngaranna spring-boot-jarmode-layertoolsи layersfle.idxberkas. file JAR tambahan ieu nyadiakeun kamampuhan processing layered, sakumaha dijelaskeun dina bagian salajengna.

Extracting kagumantungan dina lapisan individu

Pikeun ningali sareng nimba lapisan tina JAR berlapis kami, kami nganggo properti sistem -Djarmode=layertoolspikeun ngamimitian spring-boot-jarmode-layertoolsJAR tinimbang aplikasi:

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

Ngajalankeun paréntah ieu ngahasilkeun kaluaran anu ngandung pilihan paréntah anu sayogi:

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

output nembongkeun paréntah listextractи helpс helpjanten standar. Hayu urang ngajalankeun paréntah kalawan listpilihan:

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

Urang tingali daptar kagumantungan anu bisa ditambahkeun salaku lapisan.

Lapisan standar:

Ngaran lapisan

eusi

dependencies

sagala kagumantungan anu versina teu ngandung SNAPSHOT

spring-boot-loader

Kelas JAR Loader

snapshot-dependencies

sagala kagumantungan anu versi ngandung SNAPSHOT

application

kelas aplikasi jeung sumber

Lapisan dihartikeun dina layers.idxfile dina urutan maranéhna kudu ditambahkeun kana gambar Docker. Lapisan ieu disimpen dina host saatos dimeunangkeun heula sabab henteu robih. Ngan lapisan aplikasi anu diropéa anu diunduh ka host, anu langkung gancang kusabab ukuran anu dikirangan .

Ngawangun hiji gambar kalawan dependensi sasari kana lapisan misah

Urang bakal ngawangun gambar ahir dina dua tahapan ngagunakeun métode disebut assembly multi-tahap . Dina lengkah kahiji urang bakal nimba kabebasan jeung dina hambalan kadua urang bakal nyalin kabebasan sasari kana gambar ahir.

Hayu urang ngarobih Dockerfile kami pikeun ngawangun multi-tahap:

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

Urang nyimpen konfigurasi ieu dina file misah - Dockerfile2.

Urang ngawangun gambar Docker nganggo paréntah:

docker build -f Dockerfile2 -t usersignup:v1 .

Saatos ngajalankeun paréntah ieu kami nampi kaluaran ieu:

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

Urang tiasa ningali yén gambar Docker didamel nganggo ID gambar teras ditandaan.

Tungtungna, kami ngajalankeun paréntah Dive sapertos sateuacan mariksa lapisan dina gambar Docker anu dihasilkeun. Urang tiasa nyayogikeun ID gambar atanapi tag salaku input kana paréntah Dive:

dive userssignup:v1

Sakumaha anjeun tiasa tingali dina kaluaran, lapisan anu ngandung aplikasi ayeuna ngan ukur 11 KB, sareng katergantungan disimpen dina lapisan anu misah. 

Nyiptakeun Gambar Docker Dioptimalkeun pikeun Aplikasi Spring Boot

Extracting kagumantungan internal dina lapisan individu

Urang salajengna tiasa ngirangan ukuran tingkat aplikasi ku cara ngekstrak salah sahiji katergantungan khusus urang kana tingkat anu misah tibatan ngabungkus sareng aplikasi ku cara nyatakeun aranjeunna dina ymlfile sarupa ngaranna 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/"

Dina file ieu layers.idxkami parantos nambihan katergantungan khusus anu namina, io.myorgngandung katergantungan organisasi anu dicandak tina gudang anu dibagikeun.

kacindekan

Dina tulisan ieu, urang ningali ngagunakeun Cloud-Native Buildpacks pikeun ngawangun gambar wadah langsung tina kode sumber. Ieu mangrupikeun alternatif pikeun ngagunakeun Docker pikeun nyiptakeun gambar wadahna ku cara biasa: mimiti nyiptakeun file JAR anu tiasa dieksekusi kandel teras dibungkus kana gambar wadahna ku netepkeun petunjuk dina file Docker.

Kami ogé ningali ngaoptimalkeun wadahna ku ngaktifkeun fitur layering anu narik katergantungan kana lapisan anu misah anu disimpen dina host sareng lapisan ipis aplikasi dimuat dina waktos jadwal dina mesin palaksanaan wadahna.

Anjeun tiasa mendakan sadaya kode sumber anu dianggo dina tulisan di Github .

Rujukan paréntah

Ieu rundown gancang tina paréntah anu kami dianggo dina tulisan ieu.

Ngabersihan konteks:

docker system prune -a

Nyiptakeun gambar wadahna nganggo file Docker:

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

Urang ngawangun gambar wadahna tina kode sumber (tanpa Dockerfile):

mvn spring-boot:build-image

Témbongkeun lapisan kagumantungan. Sateuacan ngawangun file JAR aplikasi, pastikeun yén fitur layering diaktipkeun dina spring-boot-maven-plugin:

java -Djarmode=layertools -jar application.jar list

Extracting lapisan kagumantungan. Sateuacan ngawangun file JAR aplikasi, pastikeun yén fitur layering diaktipkeun dina spring-boot-maven-plugin:

 java -Djarmode=layertools -jar application.jar extract

Nempo daptar gambar wadahna

docker images

Témbongkeun di kénca di jero gambar wadahna (pastikeun alat beuleum dipasang):

dive <image ID or image tag>

sumber: www.habr.com