คอนเทนเนอร์กลายเป็นวิธีการที่นิยมใช้ในการบรรจุแอปพลิเคชันโดยมีการพึ่งพาซอฟต์แวร์และระบบปฏิบัติการทั้งหมด จากนั้นจึงส่งมอบไปยังสภาพแวดล้อมที่แตกต่างกัน
บทความนี้ครอบคลุมถึงวิธีต่างๆ ในการจัดเก็บแอปพลิเคชัน Spring Boot:
- การสร้างอิมเมจ Docker โดยใช้ไฟล์ Docker
- การสร้างอิมเมจ OCI จากแหล่งที่มาโดยใช้ Cloud-Native Buildpack
- และการเพิ่มประสิทธิภาพรูปภาพรันไทม์โดยการแยกส่วนของ JAR ออกเป็นเลเยอร์ต่างๆ โดยใช้เครื่องมือหลายเลเยอร์
ตัวอย่างโค้ด
บทความนี้มาพร้อมกับตัวอย่างโค้ดการทำงาน
คำศัพท์เกี่ยวกับคอนเทนเนอร์
เราจะเริ่มต้นด้วยคำศัพท์เฉพาะของคอนเทนเนอร์ที่ใช้ในบทความ:
- ภาพคอนเทนเนอร์: ไฟล์ในรูปแบบเฉพาะ เราจะแปลงแอปพลิเคชันของเราให้เป็นคอนเทนเนอร์อิมเมจโดยเรียกใช้เครื่องมือสร้าง
- ภาชนะ: อินสแตนซ์ที่ปฏิบัติการได้ของอิมเมจคอนเทนเนอร์
- เครื่องยนต์คอนเทนเนอร์: กระบวนการ daemon ที่รับผิดชอบในการรันคอนเทนเนอร์
- โฮสต์คอนเทนเนอร์: คอมพิวเตอร์โฮสต์ที่โปรแกรมคอนเทนเนอร์ทำงาน
- รีจิสทรีคอนเทนเนอร์: ตำแหน่งทั่วไปที่ใช้ในการเผยแพร่และแจกจ่ายอิมเมจคอนเทนเนอร์
- มาตรฐานโอซีไอ:
โครงการริเริ่มคอนเทนเนอร์เปิด (OCI) เป็นโครงสร้างการกำกับดูแลแบบเปิดที่มีน้ำหนักเบาซึ่งสร้างขึ้นภายใน Linux Foundation ข้อกำหนดรูปภาพ OCI กำหนดมาตรฐานอุตสาหกรรมสำหรับอิมเมจคอนเทนเนอร์และรูปแบบรันไทม์ เพื่อให้แน่ใจว่ากลไกคอนเทนเนอร์ทั้งหมดสามารถรันอิมเมจคอนเทนเนอร์ที่สร้างโดยเครื่องมือสร้างใดๆ ได้
ในการบรรจุแอปพลิเคชัน เราจะรวมแอปพลิเคชันของเราไว้ในอิมเมจคอนเทนเนอร์และเผยแพร่อิมเมจนั้นไปยังรีจีสทรีที่ใช้ร่วมกัน รันไทม์ของคอนเทนเนอร์ดึงอิมเมจนี้จากรีจิสทรี แตกไฟล์ และรันแอปพลิเคชันภายในอิมเมจ
Spring Boot เวอร์ชัน 2.3 มีปลั๊กอินสำหรับสร้างอิมเมจ OCI
การสร้างคอนเทนเนอร์อิมเมจด้วยวิธีดั้งเดิม
การสร้างอิมเมจ Docker สำหรับแอปพลิเคชัน Spring Boot นั้นง่ายมากโดยการเพิ่มคำแนะนำเล็กน้อยลงในไฟล์ Docker
ขั้นแรกเราสร้างไฟล์ JAR ที่เรียกใช้งานได้ และตามคำแนะนำของไฟล์ Docker ให้คัดลอกไฟล์ JAR ที่เรียกใช้งานได้ที่ด้านบนของอิมเมจ JRE พื้นฐานหลังจากใช้การตั้งค่าที่จำเป็น
มาสร้างแอปพลิเคชัน Spring ของเรากัน web
, lombok
и actuator
. เรายังเพิ่มตัวควบคุมส่วนที่เหลือเพื่อจัดเตรียม API ด้วย GET
กระบวนการ.
การสร้าง Dockerfile
จากนั้นเราจะจัดคอนเทนเนอร์แอปพลิเคชันนี้โดยการเพิ่ม Dockerfile
:
FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/application.jar"]
ไฟล์ Docker ของเรามีอิมเมจพื้นฐานจาก adoptopenjdk
นอกจากนี้เรายังคัดลอกไฟล์ JAR ของเราแล้วเปิดพอร์ต 8080
ซึ่งจะรับฟังคำร้องขอ
การสร้างแอปพลิเคชัน
ก่อนอื่นคุณต้องสร้างแอปพลิเคชันโดยใช้ Maven หรือ Gradle ที่นี่เราใช้ Maven:
mvn clean package
สิ่งนี้จะสร้างไฟล์ JAR ที่ปฏิบัติการได้สำหรับแอปพลิเคชัน เราจำเป็นต้องแปลง JAR ที่ปฏิบัติการได้นี้เป็นอิมเมจ Docker เพื่อทำงานบนเอ็นจิ้น Docker
การสร้างอิมเมจคอนเทนเนอร์
จากนั้นเราใส่ไฟล์ JAR ที่สามารถเรียกใช้งานได้นี้ลงในอิมเมจ Docker โดยการรันคำสั่ง docker build
จากไดเร็กทอรีรากของโปรเจ็กต์ที่มี Dockerfile ที่สร้างไว้ก่อนหน้านี้:
docker build -t usersignup:v1 .
เราสามารถเห็นภาพของเราในรายการโดยใช้คำสั่ง:
docker images
ผลลัพธ์ของคำสั่งดังกล่าวรวมถึงรูปภาพของเราด้วย usersignup
พร้อมด้วยภาพฐาน adoptopenjdk
ระบุไว้ในไฟล์ Docker ของเรา
REPOSITORY TAG SIZE
usersignup v1 249MB
adoptopenjdk 11-jre-hotspot 229MB
ดูเลเยอร์ภายในอิมเมจคอนเทนเนอร์
ลองดูที่การซ้อนกันของเลเยอร์ภายในภาพ เราจะใช้
dive usersignup:v1
นี่คือส่วนหนึ่งของเอาต์พุตจากคำสั่ง Dive:
ดังที่เราเห็น เลเยอร์แอปพลิเคชันเป็นส่วนสำคัญของขนาดรูปภาพ เราต้องการลดขนาดของเลเยอร์นี้ในส่วนต่อไปนี้ซึ่งเป็นส่วนหนึ่งของการปรับให้เหมาะสมของเรา
การสร้างอิมเมจคอนเทนเนอร์โดยใช้ Buildpack
ข้อดีของแพ็คเกจการสร้างระบบคลาวด์
ประโยชน์หลักประการหนึ่งของการใช้ Buildpack เพื่อสร้างรูปภาพก็คือ การเปลี่ยนแปลงการกำหนดค่าอิมเมจสามารถจัดการได้จากส่วนกลาง (ตัวสร้าง) และเผยแพร่ไปยังแอปพลิเคชันทั้งหมดโดยใช้ตัวสร้าง
แพ็คเกจบิลด์นั้นเชื่อมโยงกับแพลตฟอร์มอย่างแน่นหนา Cloud-Native Buildpacks มอบมาตรฐานข้ามแพลตฟอร์มโดยรองรับรูปแบบอิมเมจ OCI ซึ่งทำให้มั่นใจได้ว่าอิมเมจจะรันโดยกลไก Docker ได้
การใช้ปลั๊กอิน Spring Boot
ปลั๊กอิน Spring Boot สร้างอิมเมจ OCI จากแหล่งที่มาโดยใช้ Buildpack ภาพถูกสร้างขึ้นโดยใช้ bootBuildImage
งาน (Gradle) หรือ spring-boot:build-image
เป้าหมาย (Maven) และการติดตั้ง Docker ในเครื่อง
เราสามารถปรับแต่งชื่อของรูปภาพที่จำเป็นในการพุชไปยังรีจิสทรี Docker ได้โดยการระบุชื่อใน 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>
ลองใช้ Maven ทำดูครับ build-image
เป้าหมายสำหรับการสร้างแอปพลิเคชันและสร้างอิมเมจคอนเทนเนอร์ เราไม่ได้ใช้ Dockerfiles ใด ๆ ในขณะนี้
mvn spring-boot:build-image
ผลลัพธ์จะเป็นดังนี้:
[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'
จากผลลัพธ์เราจะเห็นว่า paketo Cloud-Native buildpack
ใช้เพื่อสร้างอิมเมจ OCI ที่ใช้งานได้ เหมือนเมื่อก่อนเราสามารถเห็นภาพที่แสดงเป็นอิมเมจ Docker ได้โดยการรันคำสั่ง:
docker images
สรุป:
REPOSITORY SIZE
paketobuildpacks/run 84.3MB
gcr.io/paketo-buildpacks/builder 652MB
pratikdas/usersignup 257MB
การสร้างอิมเมจคอนเทนเนอร์โดยใช้ Jib
Jib เป็นปลั๊กอินสร้างรูปภาพจาก Google ที่ให้วิธีการอื่นในการสร้างคอนเทนเนอร์อิมเมจจากซอร์สโค้ด
ปรับแต่ง jib-maven-plugin
ใน pom.xml:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>2.5.2</version>
</plugin>
ต่อไป เราจะรันปลั๊กอิน Jib โดยใช้คำสั่ง Maven เพื่อสร้างแอปพลิเคชันและสร้างคอนเทนเนอร์อิมเมจ เช่นเคย เราไม่ได้ใช้ไฟล์ Docker ใดๆ ที่นี่:
mvn compile jib:build -Dimage=<docker registry name>/usersignup:v1
หลังจากดำเนินการคำสั่ง Maven ข้างต้นแล้ว เราจะได้ผลลัพธ์ดังต่อไปนี้:
[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
ผลลัพธ์แสดงว่าอิมเมจคอนเทนเนอร์ถูกสร้างขึ้นและวางไว้ในรีจิสทรีแล้ว
แรงจูงใจและเทคนิคในการสร้างภาพให้เหมาะสม
เรามีเหตุผลหลักสองประการในการเพิ่มประสิทธิภาพ:
- การปฏิบัติ: ในระบบการจัดการคอนเทนเนอร์ อิมเมจคอนเทนเนอร์จะถูกดึงข้อมูลจากรีจีสทรีอิมเมจไปยังโฮสต์ที่รันกลไกจัดการคอนเทนเนอร์ กระบวนการนี้เรียกว่าการวางแผน การดึงรูปภาพขนาดใหญ่จากรีจิสทรีส่งผลให้เวลาการจัดกำหนดการนานในระบบการจัดการคอนเทนเนอร์และเวลาการสร้างนานในไปป์ไลน์ CI
- ความปลอดภัย: รูปภาพขนาดใหญ่ยังมีพื้นที่สำหรับช่องโหว่ที่ใหญ่ขึ้นด้วย
อิมเมจ Docker ประกอบด้วยเลเยอร์ซ้อนกัน ซึ่งแต่ละเลเยอร์แทนคำสั่งใน Dockerfile ของเรา แต่ละเลเยอร์แสดงถึงส่วนต่างของการเปลี่ยนแปลงในเลเยอร์ที่อยู่ด้านล่าง เมื่อเราดึงอิมเมจ Docker จากรีจิสตรี รูปภาพนั้นจะถูกดึงเป็นเลเยอร์และแคชไว้บนโฮสต์
สปริงบูทใช้
สูตรการปรับให้เหมาะสมมุ่งเน้นไปที่การแยกแอปพลิเคชันในระดับที่แยกจากการอ้างอิง Spring Framework
เลเยอร์การขึ้นต่อกันซึ่งสร้างไฟล์ JAR แบบหนาจำนวนมาก จะถูกดาวน์โหลดเพียงครั้งเดียวและแคชไว้บนระบบโฮสต์
จะมีการดึงแอปพลิเคชันเพียงชั้นบางๆ เท่านั้นในระหว่างการอัปเดตแอปพลิเคชันและการกำหนดเวลาคอนเทนเนอร์ ดังแสดงในแผนภาพนี้:
ในส่วนต่อไปนี้ เราจะดูวิธีสร้างอิมเมจที่ได้รับการปรับปรุงเหล่านี้สำหรับแอปพลิเคชัน Spring Boot
การสร้างอิมเมจคอนเทนเนอร์ที่ปรับให้เหมาะสมสำหรับแอปพลิเคชัน Spring Boot โดยใช้ Buildpack
Spring Boot 2.3 รองรับการแบ่งเลเยอร์โดยแยกส่วนของไฟล์ JAR แบบหนาออกเป็นเลเยอร์แยกกัน คุณลักษณะการแบ่งชั้นถูกปิดใช้งานตามค่าเริ่มต้น และต้องเปิดใช้งานอย่างชัดเจนโดยใช้ปลั๊กอิน Spring Boot Maven:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
เราจะใช้การกำหนดค่านี้เพื่อสร้างคอนเทนเนอร์อิมเมจของเราก่อนด้วย Buildpack จากนั้นจึงใช้ Docker ในส่วนต่อไปนี้
เปิดตัวกันเลย build-image
เป้าหมาย Maven สำหรับการสร้างอิมเมจคอนเทนเนอร์:
mvn spring-boot:build-image
หากเราเรียกใช้ Dive เพื่อดูเลเยอร์ในภาพที่ได้ เราจะเห็นว่าเลเยอร์แอปพลิเคชัน (เส้นขอบสีแดง) มีขนาดเล็กกว่ามากในช่วงกิโลไบต์ เมื่อเทียบกับสิ่งที่เราได้รับจากรูปแบบ JAR แบบหนา:
การสร้างอิมเมจคอนเทนเนอร์ที่ปรับให้เหมาะสมสำหรับแอปพลิเคชัน Spring Boot โดยใช้ Docker
แทนที่จะใช้ปลั๊กอิน Maven หรือ Gradle เรายังสามารถสร้างอิมเมจ Docker JAR แบบเลเยอร์ด้วยไฟล์ Docker ได้อีกด้วย
เมื่อเราใช้ Docker เราจำเป็นต้องดำเนินการเพิ่มเติมอีกสองขั้นตอนเพื่อแยกเลเยอร์และคัดลอกลงในภาพสุดท้าย
เนื้อหาของ JAR ที่เป็นผลลัพธ์หลังจากสร้างโดยใช้ Maven โดยเปิดใช้งานการแบ่งชั้นจะมีลักษณะดังนี้:
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
ผลลัพธ์จะแสดง JAR เพิ่มเติมที่มีชื่อ spring-boot-jarmode-layertools
и layersfle.idx
ไฟล์. ไฟล์ JAR เพิ่มเติมนี้จัดเตรียมความสามารถในการประมวลผลแบบเลเยอร์ ดังที่อธิบายไว้ในส่วนถัดไป
แยกการพึ่งพาในแต่ละเลเยอร์
หากต้องการดูและแยกเลเยอร์จาก JAR ที่แบ่งเลเยอร์ของเรา เราใช้คุณสมบัติของระบบ -Djarmode=layertools
สำหรับการเริ่มต้น spring-boot-jarmode-layertools
JAR แทนแอปพลิเคชัน:
java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar
การรันคำสั่งนี้จะสร้างเอาต์พุตที่มีตัวเลือกคำสั่งที่ใช้ได้:
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
ผลลัพธ์จะแสดงคำสั่ง list
, extract
и help
с help
เป็นค่าเริ่มต้น มารันคำสั่งด้วย list
ตัวเลือก:
java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list
dependencies
spring-boot-loader
snapshot-dependencies
application
เราเห็นรายการการขึ้นต่อกันที่สามารถเพิ่มเป็นเลเยอร์ได้
เลเยอร์เริ่มต้น:
ชื่อเลเยอร์
Содержание
dependencies
การขึ้นต่อกันใดๆ ที่เวอร์ชันไม่มี SNAPSHOT
spring-boot-loader
คลาสตัวโหลด JAR
snapshot-dependencies
การขึ้นต่อกันใดๆ ที่มีเวอร์ชันประกอบด้วย SNAPSHOT
application
คลาสแอปพลิเคชันและทรัพยากร
เลเยอร์ถูกกำหนดไว้ใน layers.idx
ตามลำดับที่ควรเพิ่มลงในอิมเมจ Docker เลเยอร์เหล่านี้ถูกแคชไว้ในโฮสต์หลังจากการดึงข้อมูลครั้งแรก เนื่องจากไม่มีการเปลี่ยนแปลง ดาวน์โหลดเฉพาะเลเยอร์แอปพลิเคชันที่อัปเดตไปยังโฮสต์ ซึ่งเร็วกว่าเนื่องจากขนาดที่ลดลง .
การสร้างภาพโดยแยกการอ้างอิงออกเป็นเลเยอร์ที่แยกจากกัน
เราจะสร้างภาพสุดท้ายในสองขั้นตอนโดยใช้วิธีการที่เรียกว่า
มาแก้ไข Dockerfile ของเราสำหรับการสร้างแบบหลายขั้นตอน:
# 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"]
เราบันทึกการกำหนดค่านี้ในไฟล์แยกต่างหาก - Dockerfile2
.
เราสร้างอิมเมจ Docker โดยใช้คำสั่ง:
docker build -f Dockerfile2 -t usersignup:v1 .
หลังจากรันคำสั่งนี้แล้ว เราจะได้ผลลัพธ์ดังนี้:
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
เราจะเห็นว่าอิมเมจ Docker ถูกสร้างขึ้นด้วย ID รูปภาพแล้วติดแท็ก
ในที่สุด เราก็รันคำสั่ง Dive เหมือนเมื่อก่อนเพื่อตรวจสอบเลเยอร์ภายในอิมเมจ Docker ที่สร้างขึ้น เราสามารถระบุ ID รูปภาพหรือแท็กเป็นอินพุตให้กับคำสั่ง Dive:
dive userssignup:v1
ดังที่คุณเห็นในผลลัพธ์ ขณะนี้เลเยอร์ที่มีแอปพลิเคชันมีขนาดเพียง 11 KB และการขึ้นต่อกันจะถูกแคชในเลเยอร์ที่แยกจากกัน
แยกการพึ่งพาภายในของแต่ละเลเยอร์
เราสามารถลดขนาดของระดับแอปพลิเคชันเพิ่มเติมได้โดยแยกการพึ่งพาที่กำหนดเองใดๆ ของเราออกเป็นระดับที่แยกจากกัน แทนที่จะบรรจุลงในแอปพลิเคชันโดยการประกาศไว้ใน yml
ชื่อไฟล์ที่คล้ายกัน 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/"
ในไฟล์นี้ layers.idx
เราได้เพิ่มการพึ่งพาที่กำหนดเองชื่อ io.myorg
มีการพึ่งพาองค์กรที่ดึงมาจากพื้นที่เก็บข้อมูลที่ใช้ร่วมกัน
เอาท์พุต
ในบทความนี้ เรามาดูการใช้ Cloud-Native Buildpacks เพื่อสร้างคอนเทนเนอร์อิมเมจจากซอร์สโค้ดโดยตรง นี่เป็นอีกทางเลือกหนึ่งนอกเหนือจากการใช้ Docker เพื่อสร้างอิมเมจคอนเทนเนอร์ด้วยวิธีปกติ โดยขั้นแรกให้สร้างไฟล์ JAR ที่สามารถเรียกใช้งานได้แบบหนา จากนั้นจึงบรรจุลงในอิมเมจคอนเทนเนอร์โดยระบุคำแนะนำในไฟล์ Docker
นอกจากนี้เรายังดูที่การเพิ่มประสิทธิภาพคอนเทนเนอร์ของเราด้วยการเปิดใช้งานคุณลักษณะการแบ่งชั้นที่ดึงการขึ้นต่อกันลงในเลเยอร์ที่แยกจากกันซึ่งถูกแคชไว้บนโฮสต์ และเลเยอร์บาง ๆ ของแอปพลิเคชันจะถูกโหลดตามเวลาที่กำหนดในกลไกการทำงานของคอนเทนเนอร์
คุณสามารถค้นหาซอร์สโค้ดทั้งหมดที่ใช้ในบทความได้ที่
การอ้างอิงคำสั่ง
ต่อไปนี้คือบทสรุปโดยย่อของคำสั่งที่เราใช้ในบทความนี้
การล้างบริบท:
docker system prune -a
การสร้างอิมเมจคอนเทนเนอร์โดยใช้ไฟล์ Docker:
docker build -f <Docker file name> -t <tag> .
เราสร้างคอนเทนเนอร์อิมเมจจากซอร์สโค้ด (ไม่มี Dockerfile):
mvn spring-boot:build-image
ดูเลเยอร์การพึ่งพา ก่อนที่จะสร้างไฟล์ JAR ของแอปพลิเคชัน ตรวจสอบให้แน่ใจว่าได้เปิดใช้งานคุณสมบัติการแบ่งชั้นใน spring-boot-maven-plugin:
java -Djarmode=layertools -jar application.jar list
แยกชั้นการพึ่งพา ก่อนที่จะสร้างไฟล์ JAR ของแอปพลิเคชัน ตรวจสอบให้แน่ใจว่าได้เปิดใช้งานคุณสมบัติการแบ่งชั้นใน spring-boot-maven-plugin:
java -Djarmode=layertools -jar application.jar extract
ดูรายการอิมเมจคอนเทนเนอร์
docker images
ดูทางด้านซ้ายภายในอิมเมจคอนเทนเนอร์ (ตรวจสอบให้แน่ใจว่าได้ติดตั้งเครื่องมือดำน้ำแล้ว):
dive <image ID or image tag>
ที่มา: will.com