Mengurangi ukuran gambar buruh pelabuhan dengan aplikasi booting pegas

Selamat siang


Baru-baru ini, saya menghadapi tugas meluncurkan aplikasi spring boot 2 di cluster kubernetes menggunakan gambar buruh pelabuhan. Masalah ini bukan hal baru, cukup cepat saya menemukan contoh di Google dan mengemas aplikasi saya. Saya sangat terkejut tidak menemukan gambar alpine untuk jdk11 dan berharap bahwa ramping akan cukup kecil, tetapi ketika saya mengirim gambar ke registri buruh pelabuhan, saya perhatikan bahwa ukurannya hampir 422 megabyte. Di bawah kucing adalah deskripsi tentang bagaimana saya mengurangi gambar buruh pelabuhan dengan boot spring saya dan java 11 hingga 144 megabyte.



Aplikasi


Seperti yang saya sebutkan sebelumnya, aplikasi saya dibangun menggunakan spring boot 2 dan merupakan pembungkus REST API atas database relasional (menggunakan @RepositoryRestResource). Ketergantungan saya meliputi:


org.springframework.boot:spring-boot-starter-data-rest org.springframework.boot:spring-boot-starter-data-jpa org.flywaydb:flyway-core org.postgresql:postgresql 

File jar yang dikumpulkan memiliki ukuran 37,6 megabita.


Dockerfile:


 FROM openjdk:11-jdk-slim WORKDIR /home/demo ARG REVISION COPY target/spring-boot-app-${REVISION}.jar app.jar ENTRYPOINT ["java","-jar","app.jar"] 

Sebagai hasil dari perakitan, saya mendapatkan gambar ukuran: 422 mb sesuai dengan output dari perintah gambar buruh pelabuhan. Menariknya, saat menggunakan gambar 8-jdk-slim yang ketinggalan zaman, ukurannya dikurangi menjadi 306 mb.


Percobaan 1: Gambar Dasar Lainnya


Langkah logis pertama adalah upaya untuk menemukan gambar yang lebih ringan, lebih disukai berdasarkan alpine. Saya memindai repositori Java paling populer:



(11 sebagai rilis LTS saat ini dan 8 karena masih ada cukup banyak aplikasi yang tidak dapat bermigrasi ke versi yang lebih modern)


Tabel dengan gambar dan tag (~ 2700), ukurannya pada saat penulisan tersedia di sini


Inilah beberapa di antaranya:


 openjdk 8 488MB openjdk 8-slim 269MB openjdk 8-alpine 105MB openjdk 8-jdk-slim 269MB openjdk 8-jdk-alpine 105MB openjdk 8-jre 246MB openjdk 8-jre-slim 168MB openjdk 8-jre-alpine 84.9MB openjdk 11 604MB openjdk 11-slim 384MB openjdk 11-jdk 604MB openjdk 11-jdk-slim 384MB openjdk 11-jre 479MB openjdk 11-jre-slim 273MB adoptopenjdk/openjdk8 alpine 221MB adoptopenjdk/openjdk8 alpine-slim 89.7MB adoptopenjdk/openjdk8 jre 200MB adoptopenjdk/openjdk8 alpine-jre 121MB adoptopenjdk/openjdk11 alpine 337MB adoptopenjdk/openjdk11 alpine-slim 246MB adoptopenjdk/openjdk11 jre 218MB adoptopenjdk/openjdk11 alpine-jre 140MB 

Jadi, jika Anda mengubah gambar dasar menjadi adoptopenjdk / openjdk11: alpine-jre, Anda dapat mengurangi gambar dengan aplikasi menjadi 177 mb.


Percobaan 2: runtime khusus


Sejak rilis jdk9 dan modularisasi, menjadi mungkin untuk membangun runtime Anda sendiri yang hanya berisi modul-modul yang diperlukan untuk aplikasi Anda. Anda dapat membaca lebih lanjut tentang fungsi ini di sini .


Mari kita coba untuk menentukan modul yang diperlukan untuk aplikasi boot uji pegas:


 ~/app ᐅ jdeps -s target/app-1.0.0.jar app-1.0.0.jar -> java.base app-1.0.0.jar -> java.logging app-1.0.0.jar -> not found 

Ok, sepertinya jdeps tidak bisa menangani guci gemuk yang dibuat dengan booting musim semi, tetapi kita dapat meng-unzip arsip dan menulis classpath:


 ~/app ᐅ jdeps -s -cp target/app-1.0.0/BOOT-INF/lib/*.jar target/app-1.0.0.jar.original Error: byte-buddy-1.9.12.jar is a multi-release jar file but --multi-release option is not set ~/app ᐅ jdeps -s --multi-release 11 -cp target/app-1.0.0/BOOT-INF/lib/*.jar target/app-1.0.0.jar.original Error: aspectjweaver-1.9.2.jar is not a multi-release jar file but --multi-release option is set 

Pada kesempatan ini, bug saat ini terbuka: https://bugs.openjdk.java.net/browse/JDK-8207162


Saya mencoba mengunduh jdk12 untuk mendapatkan informasi ini, tetapi mengalami kesalahan berikut:


 Exception in thread "main" com.sun.tools.classfile.Dependencies$ClassFileError ... Caused by: com.sun.tools.classfile.ConstantPool$InvalidEntry: unexpected tag at #1: 53 

Dengan percobaan, kesalahan dan pencarian modul oleh ClassNotFoundException, saya memutuskan bahwa aplikasi saya membutuhkan modul-modul berikut:


  • java.base
  • java.logging
  • java.sql
  • java.naming
  • manajemen java
  • instrumen java
  • java.desktop
  • java.security.jgss

Rantime untuk mereka dapat dikumpulkan menggunakan:


 jlink --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules java.base,java.logging,java.sql,java.naming,java.management,java.instrument,java.desktop,java.security.jgss --output /usr/lib/jvm/spring-boot-runtime 

Mari kita coba membangun gambar buruh pelabuhan dasar menggunakan modul ini:


 FROM openjdk:11-jdk-slim RUN jlink --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules java.base,java.logging,java.sql,java.naming,java.management,java.instrument,java.desktop,java.security.jgss --output /usr/lib/jvm/spring-boot-runtime FROM debian:stretch-slim COPY --from=0 /usr/lib/jvm/spring-boot-runtime /usr/lib/jvm/spring-boot-runtime RUN ln -s /usr/lib/jvm/spring-boot-runtime/bin/java /usr/bin/java 

dan kumpulkan:


 docker build . -t spring-boot-runtime:openjdk-11-slim 

Hasilnya, ukurannya adalah 106 megabita, yang jauh lebih kecil daripada kebanyakan gambar dasar yang ditemukan dengan openjdk. Jika Anda menggunakannya untuk aplikasi saya, maka ukuran yang dihasilkan akan 144 megabyte.


Selanjutnya, kita dapat menggunakan spring-boot-runtime:openjdk-11-slim sebagai gambar dasar untuk semua aplikasi booting semi jika mereka memiliki dependensi yang sama. Dalam kasus berbagai dependensi, dimungkinkan untuk menggunakan rakitan gambar bertingkat untuk setiap aplikasi di mana java runtime akan dikumpulkan pada tahap pertama, dan arsip dengan aplikasi akan ditambahkan pada tahap kedua.


 FROM openjdk:11-jdk-slim RUN jlink --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules java.base,YOUR_MODULES --output /usr/lib/jvm/spring-boot-runtime FROM debian:stretch-slim COPY --from=0 /usr/lib/jvm/spring-boot-runtime /usr/lib/jvm/spring-boot-runtime WORKDIR /home/demo ARG REVISION COPY target/app-${REVISION}.jar app.jar ENTRYPOINT ["/usr/lib/jvm/spring-boot-runtime/bin/java","-jar","app.jar"] 

Kesimpulan


Saat ini, sebagian besar gambar buruh pelabuhan untuk java memiliki volume yang cukup besar, yang dapat secara negatif mempengaruhi waktu mulai aplikasi, terutama jika lapisan yang diperlukan belum di server. Menggunakan tag dengan jre atau menggunakan modularisasi java, Anda dapat membangun runtime Anda sendiri, yang secara signifikan akan mengurangi ukuran gambar aplikasi.

Source: https://habr.com/ru/post/id457476/


All Articles