Nggawe Gambar Docker sing Dioptimalake kanggo Aplikasi Boot Spring

Wadah wis dadi cara sing disenengi kanggo ngemas aplikasi kanthi kabeh piranti lunak lan dependensi sistem operasi banjur dikirim menyang lingkungan sing beda-beda.

Artikel iki nyakup macem-macem cara kanggo ngemot aplikasi Spring Boot:

  • nggawe gambar Docker nggunakake file Docker,
  • nggawe gambar OCI saka sumber nggunakake Cloud-Native Buildpack,
  • lan optimasi gambar mbukak-wektu kanthi misahake bagean JAR menyang lapisan sing beda-beda nggunakake alat multi-tier.

 Tuladha kode

Artikel iki diiringi conto kode kerja ing GitHub .

Terminologi wadhah

Kita bakal miwiti nganggo terminologi wadah sing digunakake ing artikel kasebut:

  • Gambar wadhah: file saka format tartamtu. Kita bakal ngowahi aplikasi kita dadi gambar wadhah kanthi mbukak alat mbangun.
  • Container: Kayata eksekusi saka gambar wadhah.
  • Mesin kontainer: Proses daemon tanggung jawab kanggo mbukak wadhah.
  • Host wadhah: Komputer inang kang mesin wadhah mlaku.
  • Registry wadhah: Lokasi umum sing digunakake kanggo nerbitake lan nyebarake gambar wadhah.
  • standar OCIOpen Container Initiative (OCI) minangka struktur pamrentahan sing entheng lan mbukak sing dibentuk ing Yayasan Linux. Spesifikasi Gambar OCI nemtokake standar industri kanggo gambar wadhah lan format runtime kanggo mesthekake yen kabeh mesin wadhah bisa mbukak gambar wadhah sing digawe dening alat mbangun.

Kanggo ngemot aplikasi, kita mbungkus aplikasi ing gambar wadhah lan nerbitake gambar kasebut menyang pendaptaran sing dienggo bareng. Runtime wadhah njupuk gambar iki saka registri, mbongkar, lan mbukak aplikasi ing njero.

Versi 2.3 saka Spring Boot nyedhiyakake plugin kanggo nggawe gambar OCI.

docker minangka implementasi wadhah sing paling umum digunakake, lan kita nggunakake Docker ing conto, supaya kabeh referensi wadhah sabanjure ing artikel iki bakal ngrujuk menyang Docker.

Nggawe gambar wadhah kanthi cara tradisional

Nggawe gambar Docker kanggo aplikasi Spring Boot gampang banget kanthi nambahake sawetara instruksi menyang file Docker.

Kita nggawe file JAR sing bisa dieksekusi lan, minangka bagean saka instruksi file Docker, nyalin file JAR sing bisa dieksekusi ing ndhuwur gambar JRE dhasar sawise ngetrapake setelan sing dibutuhake.

Ayo nggawe aplikasi Spring kita ing Spring Initializr karo dependensi weblombokΠΈ actuator. Kita uga nambah controller liyane kanggo nyedhiyani API karo GETcara.

Nggawe Dockerfile

Kita banjur containerize aplikasi iki kanthi nambah 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 kita ngemot gambar dhasar saka adoptopenjdk, ing ndhuwur kita nyalin file JAR banjur mbukak port kasebut, 8080kang bakal ngrungokake panjalukan.

Nggawe aplikasi

Pisanan sampeyan kudu nggawe aplikasi nggunakake Maven utawa Gradle. Ing kene kita nggunakake Maven:

mvn clean package

Iki nggawe file JAR sing bisa dieksekusi kanggo aplikasi kasebut. Kita kudu ngowahi JAR eksekusi iki dadi gambar Docker kanggo mbukak mesin Docker.

Nggawe gambar wadhah

Banjur sijine file JAR sing bisa dieksekusi iki menyang gambar Docker kanthi nglakokake perintah kasebut docker buildsaka direktori root proyek sing ngemot Dockerfile sing digawe sadurunge:

docker build  -t usersignup:v1 .

Kita bisa ndeleng gambar kita ing dhaptar nggunakake printah:

docker images 

Output saka printah ing ndhuwur kalebu gambar kita usersignupbebarengan karo gambar dhasar, adoptopenjdkkasebut ing file Docker kita.

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

Deleng lapisan ing gambar wadhah

Ayo ndeleng tumpukan lapisan ing gambar kasebut. Kita bakal nggunakake alat  nyilem kanggo ndeleng lapisan iki:

dive usersignup:v1

Iki minangka bagean saka output saka printah Dive: 

Nggawe Gambar Docker sing Dioptimalake kanggo Aplikasi Boot Spring

Minangka kita bisa ndeleng, lapisan aplikasi nggawe bagean sing signifikan saka ukuran gambar. Kita pengin nyuda ukuran lapisan iki ing bagean ing ngisor iki minangka bagΓ©an saka optimasi kita.

Nggawe gambar wadhah nggunakake Buildpack

Paket perakitan (Buildpacks) minangka istilah umum sing digunakake dening macem-macem Platform minangka Layanan (PAAS) kanggo nggawe gambar wadhah saka kode sumber. Iki diluncurake dening Heroku ing 2011 lan wiwit diadopsi dening Cloud Foundry, Google App Engine, Gitlab, Knative lan sawetara liyane.

Nggawe Gambar Docker sing Dioptimalake kanggo Aplikasi Boot Spring

Kauntungan saka paket mbangun awan

Salah sawijining keuntungan utama nggunakake Buildpack kanggo nggawe gambar yaiku Owah-owahan konfigurasi gambar bisa diatur kanthi pusat (pembangun) lan disebarake menyang kabeh aplikasi nggunakake pembangun.

Paket mbangun padha digandhengake karo platform. Cloud-Native Buildpacks nyedhiyakake standarisasi ing antarane platform kanthi ndhukung format gambar OCI, sing njamin gambar kasebut bisa ditindakake dening mesin Docker.

Nggunakake plugin Spring Boot

Plugin Spring Boot nggawe gambar OCI saka sumber nggunakake Buildpack. Gambar digawe nggunakake bootBuildImagetugas (Gradle) utawa spring-boot:build-imagetarget (Maven) lan instalasi Docker lokal.

Kita bisa ngatur jeneng gambar sing dibutuhake kanggo push menyang registri Docker kanthi nemtokake jeneng ing 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>

Ayo nggunakake Maven kanggo nindakake build-imagegol kanggo nggawe aplikasi lan nggawe gambar wadhah. Kita ora nggunakake file Docker ing wektu iki.

mvn spring-boot:build-image

Asil bakal kaya iki:

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

Saka output kita waca sing paketo Cloud-Native buildpackdigunakake kanggo nggawe gambar OCI sing bisa digunakake. Kaya sadurunge, kita bisa ndeleng gambar sing kadhaptar minangka gambar Docker kanthi nglakokake prentah:

docker images 

Kesimpulan:

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

Nggawe gambar wadhah nggunakake Jib

Jib minangka plugin nggawe gambar saka Google sing menehi cara alternatif kanggo nggawe gambar wadhah saka kode sumber.

Ngatur jib-maven-plugining pom.xml:

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

Sabanjure, kita mbukak plugin Jib nggunakake printah Maven kanggo mbangun aplikasi lan nggawe gambar wadhah. Kaya sadurunge, kita ora nggunakake file Docker ing kene:

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

Sawise nglakokake perintah Maven ing ndhuwur, kita entuk output ing ngisor iki:

[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

Output nuduhake yen gambar wadhah wis digawe lan diselehake ing pendaptaran.

Motivasi lan teknik kanggo nggawe gambar sing dioptimalake

Kita duwe rong alasan utama kanggo ngoptimalake:

  • Produktivitas: Ing sistem orkestrasi wadhah, gambar wadhah dijupuk saka registri gambar menyang host sing nganggo mesin wadhah. Proses iki diarani planning. Narik gambar gedhe saka registri nyebabake wektu jadwal sing dawa ing sistem orkestrasi wadhah lan wektu mbangun sing dawa ing pipa CI.
  • Keamanan: Gambar sing luwih gedhe uga nduweni area sing luwih gedhe kanggo kerentanan.

Gambar Docker kasusun saka tumpukan lapisan, sing saben makili instruksi ing Dockerfile kita. Saben lapisan nggambarake delta saka owah-owahan ing lapisan sing ndasari. Nalika kita narik gambar Docker saka pendaptaran, ditarik ing lapisan lan cache ing host.

Spring Boot nggunakake "JAR lemak" ing minangka format kemasan standar. Nalika kita ndeleng JAR kandel, kita waca manawa aplikasi nggawe bagean cilik saka kabeh JAR. Iki minangka bagΓ©an sing paling kerep diganti. Sisane kasusun saka dependensi Spring Framework.

Rumus optimasi pusat babagan ngisolasi aplikasi ing tingkat sing kapisah saka dependensi Spring Framework.

Lapisan ketergantungan, sing dadi akeh file JAR sing kandel, diundhuh mung sapisan lan di-cache ing sistem host.

Mung lapisan tipis aplikasi sing ditarik sajrone nganyari aplikasi lan jadwal wadhah. minangka ditampilake ing diagram iki:

Nggawe Gambar Docker sing Dioptimalake kanggo Aplikasi Boot Spring

Ing bagean ing ngisor iki, kita bakal ndeleng carane nggawe gambar sing dioptimalake kanggo aplikasi Spring Boot.

Nggawe Gambar Wadhah sing Dioptimalake kanggo Aplikasi Spring Boot Nggunakake Buildpack

Spring Boot 2.3 ndhukung layering kanthi ngekstrak bagean file JAR sing kandel menyang lapisan sing kapisah. Fitur layering dipateni kanthi gawan lan kudu diaktifake kanthi jelas nggunakake plugin Spring Boot Maven:

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

Kita bakal nggunakake konfigurasi iki kanggo mbangun gambar wadhah kita dhisik karo Buildpack banjur karo Docker ing bagean ing ngisor iki.

Ayo diluncurake build-imageTarget maven kanggo nggawe gambar wadah:

mvn spring-boot:build-image

Yen kita mbukak Dive kanggo ndeleng lapisan ing gambar sing diasilake, kita bisa ndeleng manawa lapisan aplikasi (digambarake kanthi warna abang) luwih cilik ing kisaran kilobyte dibandhingake karo format JAR sing kandel:

Nggawe Gambar Docker sing Dioptimalake kanggo Aplikasi Boot Spring

Nggawe Gambar Kontainer sing Dioptimalake kanggo Aplikasi Spring Boot Nggunakake Docker

Tinimbang nggunakake plugin Maven utawa Gradle, kita uga bisa nggawe gambar Docker JAR kanthi file Docker.

Nalika nggunakake Docker, kita kudu nindakake rong langkah tambahan kanggo ngekstrak lapisan lan nyalin menyang gambar pungkasan.

Isi saka JAR asil sawise mbangun nggunakake Maven karo layering aktif bakal katon kaya iki:

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 nuduhake JAR tambahan jenenge spring-boot-jarmode-layertoolsΠΈ layersfle.idxberkas. File JAR tambahan iki nyedhiyakake kemampuan pangolahan lapisan, kaya sing diterangake ing bagean sabanjure.

Ekstrak dependensi ing lapisan individu

Kanggo ndeleng lan ngekstrak lapisan saka JAR berlapis, kita nggunakake properti sistem -Djarmode=layertoolskanggo wiwitan spring-boot-jarmode-layertoolsJAR tinimbang aplikasi:

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

Mlaku printah iki ngasilake output sing ngemot opsi printah sing kasedhiya:

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 nuduhake printah listextractΠΈ helpс helpdadi standar. Ayo dadi mbukak printah karo listpilihan:

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

Kita ndeleng dhaptar dependensi sing bisa ditambahake minangka lapisan.

Lapisan standar:

Jeneng lapisan

Isi

dependencies

sembarang dependensi kang versi ora ngemot SNAPSHOT

spring-boot-loader

Kelas JAR Loader

snapshot-dependencies

sembarang dependensi kang versi ngemot SNAPSHOT

application

kelas aplikasi lan sumber daya

Lapisan ditetepake ing layers.idxfile ing urutan sing kudu ditambahake menyang gambar Docker. Lapisan kasebut di-cache ing host sawise njupuk pisanan amarga ora owah. Mung lapisan aplikasi sing dianyari sing diundhuh menyang host, sing luwih cepet amarga ukurane suda .

Nggawe gambar kanthi dependensi sing diekstrak menyang lapisan sing kapisah

Kita bakal mbangun gambar pungkasan ing rong tahap nggunakake metode sing diarani perakitan multi-tataran . Ing langkah pisanan, kita bakal ngekstrak dependensi lan ing langkah kapindho kita bakal nyalin dependensi sing diekstrak menyang gambar pungkasan.

Ayo ngowahi Dockerfile kita kanggo mbangun 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"]

Kita nyimpen konfigurasi iki ing file sing kapisah - Dockerfile2.

Kita mbangun gambar Docker nggunakake printah:

docker build -f Dockerfile2 -t usersignup:v1 .

Sawise nindakake printah iki, kita entuk output ing ngisor iki:

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

Kita bisa ndeleng manawa gambar Docker digawe nganggo ID gambar banjur diwenehi tag.

Pungkasan, kita mbukak printah Dive kaya sadurunge kanggo mriksa lapisan ing gambar Docker sing digawe. Kita bisa nyedhiyani ID gambar utawa tag minangka input kanggo printah Dive:

dive userssignup:v1

Minangka sampeyan bisa ndeleng ing output, lapisan sing ngemot aplikasi saiki mung 11 KB, lan dependensi disimpen ing lapisan sing kapisah. 

Nggawe Gambar Docker sing Dioptimalake kanggo Aplikasi Boot Spring

Ekstrak dependensi internal ing lapisan individu

Kita bisa nyuda ukuran tingkat aplikasi kanthi ngekstrak sembarang dependensi khusus menyang tingkat sing kapisah tinimbang ngemas aplikasi kasebut kanthi nyatakake ing ymlfile sing padha jenenge 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/"

Ing file iki layers.idxkita wis nambahake dependensi khusus jenenge, io.myorgngemot dependensi organisasi sing dijupuk saka gudang sing dienggo bareng.

kesimpulan

Ing artikel iki, kita ndeleng nggunakake Cloud-Native Buildpacks kanggo nggawe gambar wadhah langsung saka kode sumber. Iki minangka alternatif kanggo nggunakake Docker kanggo nggawe gambar wadhah kanthi cara sing biasa: nggawe file JAR eksekusi sing kandel lan banjur dibungkus menyang gambar wadhah kanthi nemtokake instruksi ing file Docker.

Kita uga ndeleng ngoptimalake wadhah kanthi ngaktifake fitur layering sing narik dependensi menyang lapisan kapisah sing di-cache ing host lan lapisan tipis aplikasi dimuat ing wektu jadwal ing mesin eksekusi wadhah.

Sampeyan bisa nemokake kabeh kode sumber sing digunakake ing artikel ing GitHub .

Referensi printah

Mangkene ringkesan prentah sing digunakake ing artikel iki.

Mbusak konteks:

docker system prune -a

Nggawe gambar wadhah nggunakake file Docker:

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

Kita mbangun gambar wadhah saka kode sumber (tanpa Dockerfile):

mvn spring-boot:build-image

Ndeleng lapisan dependensi. Sadurunge mbangun file JAR aplikasi, priksa manawa fitur layering diaktifake ing spring-boot-maven-plugin:

java -Djarmode=layertools -jar application.jar list

Ekstrak lapisan dependensi. Sadurunge mbangun file JAR aplikasi, priksa manawa fitur layering diaktifake ing spring-boot-maven-plugin:

 java -Djarmode=layertools -jar application.jar extract

Deleng dhaptar gambar wadhah

docker images

Deleng ing sisih kiwa ing jero gambar wadhah (priksa manawa alat nyilem wis diinstal):

dive <image ID or image tag>

Source: www.habr.com