ProHoster > Blog > İdarə > Spring Boot Tətbiqi üçün Optimallaşdırılmış Docker Şəkillərinin qurulması
Spring Boot Tətbiqi üçün Optimallaşdırılmış Docker Şəkillərinin qurulması
Konteynerlər proqramın bütün proqram təminatı və əməliyyat sistemindən asılılıqları ilə qablaşdırma və sonra onları müxtəlif mühitlərə çatdırmaq üçün üstünlük verilən vasitəyə çevrilmişdir.
Bu məqalə Spring Boot tətbiqini konteynerləşdirməyin müxtəlif yollarını əhatə edir:
docker faylından istifadə edərək docker təsvirinin yaradılması,
Cloud-Native Buildpack istifadə edərək mənbədən OCI təsvirinin yaradılması,
və laylı alətlərdən istifadə etməklə JAR hissələrini müxtəlif səviyyələrə ayırmaqla iş vaxtında təsvirin optimallaşdırılması.
Kod nümunəsi
Bu məqalə iş kodu nümunəsi ilə müşayiət olunur GitHub-da .
Konteyner terminologiyası
Məqalədə istifadə olunan konteyner terminologiyası ilə başlayacağıq:
Konteyner: Konteyner şəklinin icra edilə bilən nümunəsi.
Konteyner mühərriki: Konteyneri işə salmaqdan məsul olan demon prosesi.
Konteyner sahibi: Konteyner mühərrikinin işlədiyi əsas maşın.
Konteyner reyestri: Konteyner şəklini dərc etmək və yaymaq üçün istifadə olunan ümumi yer.
OCI standartı: Açıq Konteyner Təşəbbüsü (OCI) Linux Fondu tərəfindən yaradılmış yüngül, açıq mənbəli idarəetmə çərçivəsidir. OCI Şəkil Spesifikasiyası konteyner təsvir formatları üçün sənaye standartlarını və bütün konteyner mühərriklərinin hər hansı bir qurma aləti tərəfindən yaradılmış konteyner şəkillərini işlədə bilməsini təmin etmək üçün iş vaxtını müəyyən edir.
Tətbiqi konteynerləşdirmək üçün tətbiqimizi konteyner şəklinə bükürük və həmin şəkli ictimai reyestrdə dərc edirik. Konteynerin işləmə vaxtı bu təsviri reyestrdən alır, paketdən çıxarır və onun daxilindəki proqramı işə salır.
Spring Boot-un 2.3 versiyası OCI şəkillərinin yaradılması üçün plaginləri təmin edir.
yükvuran ən çox istifadə edilən konteyner tətbiqidir və biz nümunələrimizdə Docker-dən istifadə edirik, buna görə də bu məqalədəki bütün sonrakı konteyner istinadları Docker-ə istinad edəcək.
Ənənəvi şəkildə konteyner təsvirinin qurulması
Spring Boot proqramları üçün Docker şəkillərini yaratmaq, Dockerfile-ə bir neçə təlimat əlavə etməklə çox asandır.
Biz əvvəlcə icra edilə bilən JAR yaradırıq və Dockerfile təlimatlarının bir hissəsi kimi, lazımi fərdiləşdirmələri tətbiq etdikdən sonra icra edilə bilən JAR-ı əsas JRE şəklinin üstünə kopyalayırıq.
Gəlin Bahar tətbiqimizi yaradaq Bahar başlanğıcı asılılıqlarla web, lombokи actuator. API təmin etmək üçün istirahət nəzarətçisi də əlavə edirik GETüsul.
Dockerfile yaradılması
Sonra bu proqramı əlavə edərək konteynerə yerləşdiririk Dockerfile:
Bizim Dockerfaylımız əsas təsvirdən ibarətdir adoptopenjdk, bunun üzərinə JAR faylımızı kopyalayırıq və sonra portu açırıq, 8080istəkləri dinləyəcək.
Tətbiq montajı
Əvvəlcə Maven və ya Gradle istifadə edərək proqram yaratmalısınız. Burada Maven istifadə edirik:
mvn clean package
Bu proqram üçün icra edilə bilən JAR faylı yaradır. Docker mühərrikində işləmək üçün bu icra edilə bilən JAR-ı Docker təsvirinə çevirməliyik.
Konteyner şəkli yaradın
Daha sonra əmri işlətməklə bu JAR icra olunanı Docker təsvirinə yerləşdirdik docker builddaha əvvəl yaradılmış Dockerfile olan layihənin kök kataloqundan:
docker build -t usersignup:v1 .
Biz öz şəklimizi komanda ilə siyahıda görə bilərik:
docker images
Yuxarıdakı əmrin çıxışı bizim şəklimizi ehtiva edir usersignupəsas şəkil ilə birlikdə, adoptopenjdkDockerfile-də müəyyən edilmişdir.
REPOSITORY TAG SIZE
usersignup v1 249MB
adoptopenjdk 11-jre-hotspot 229MB
Konteyner şəklinin içərisindəki təbəqələrə baxın
Şəklin içərisində olan təbəqə yığınına baxaq. istifadə edəcəyik alət dalış, Bu təbəqələrə baxmaq üçün:
dive usersignup:v1
Budur Dive əmrinin çıxışının bir hissəsi:
Gördüyümüz kimi, tətbiq təbəqəsi təsvir ölçüsünün əhəmiyyətli bir hissəsini təşkil edir. Biz optimallaşdırmamızın bir hissəsi olaraq aşağıdakı bölmələrdə bu təbəqənin ölçüsünü azaltmaq istəyirik.
Buildpack ilə konteyner şəklinin qurulması
Montaj paketləri (Quraşdırma paketləri) mənbə kodundan konteyner şəkli yaratmaq üçün müxtəlif Platforma Xidmət kimi (PAAS) təklifləri tərəfindən istifadə olunan ümumi termindir. 2011-ci ildə Heroku tərəfindən istifadəyə verilmiş və o vaxtdan Cloud Foundry, Google App Engine, Gitlab, Knative və bir neçə başqa şirkət tərəfindən qəbul edilmişdir.
Bulud Quraşdırma Paketlərinin Üstünlüyü
Şəkillər yaratmaq üçün Buildpack istifadə etməyin əsas üstünlüklərindən biri budur image konfiqurasiya dəyişiklikləri mərkəzləşdirilmiş şəkildə idarə oluna bilər (yaradıcı) və qurucudan istifadə edərək bütün tətbiqlərə yayıla bilər.
Quraşdırma paketləri platforma ilə sıx bağlı idi. Cloud-Native Buildpacks OCI təsvir formatını dəstəkləməklə platformalar arasında standartlaşdırma təmin edir ki, bu da təsvirin Docker mühərriki tərəfindən idarə olunmasını təmin edir.
Spring Boot Plugin istifadə edərək
Spring Boot plagini Buildpack istifadə edərək mənbədən OCI şəkillərini qurur. Şəkillər istifadə edərək yaradılır bootBuildImagetapşırıqlar (Gradle) və ya spring-boot:build-imagehədəf (Maven) və yerli Docker quraşdırılması.
Adı qeyd etməklə Docker reyestrinə köçürməli olduğumuz şəklin adını fərdiləşdirə bilərik. image tag:
İcra etmək üçün Maven-dən istifadə edək build-imageproqram yaratmaq və konteyner şəkli yaratmaq məqsədləri. Hazırda heç bir Dockerfiles istifadə etmirik.
Çıxışdan bunu görürük paketo Cloud-Native buildpackişləyən OCI təsviri yaratmaq üçün istifadə olunur. Əvvəlki kimi, biz əmri işlətməklə Docker təsviri kimi qeyd olunan şəkli görə bilərik:
Sonra, tətbiqi qurmaq və konteyner şəklini yaratmaq üçün Maven əmrindən istifadə edərək Jib plaginini işə salırıq. Əvvəlki kimi, biz burada heç bir Dockerfiles istifadə etmirik:
Yuxarıdakı Maven əmrini yerinə yetirdikdən sonra aşağıdakı nəticəni alırıq:
[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
Çıxış, konteyner şəklinin yaradıldığını və reyestrdə yerləşdirildiyini göstərir.
Optimallaşdırılmış şəkillər yaratmaq üçün motivlər və üsullar
Optimallaşdırmağın iki əsas səbəbi var:
Məhsuldarlıq: Konteynerin orkestrasiya sistemində konteyner təsviri təsvir reyestrindən konteyner mühərriki ilə işləyən hosta çəkilir. Bu proses planlaşdırma adlanır. Reyestrdən böyük şəkillərin çıxarılması konteyner orkestrləşdirmə sistemlərində uzun planlaşdırma vaxtlarına və CI boru kəmərlərində uzun qurma vaxtlarına səbəb olur.
təhlükəsizlik: böyük şəkillərdə zəifliklər üçün də geniş sahə var.
Docker təsviri hər biri Dockerfile-də ifadəni təmsil edən təbəqələr yığınından ibarətdir. Hər bir təbəqə alt qatdakı dəyişikliklərin deltasını təmsil edir. Reyestrdən Docker şəklini çəkdiyimiz zaman o, təbəqələrə çəkilir və hostda keşlənir.
Spring Boot istifadə edir "yağlı jar" içində standart qablaşdırma formatı kimi. Yağlı bir JAR-a baxdıqda, tətbiqin bütün JAR-ın çox kiçik bir hissəsi olduğunu görürük. Bu, ən çox dəyişən hissədir. Qalanları Spring Framework asılılıqlarından ibarətdir.
Optimallaşdırma düsturu tətbiqi Spring Framework asılılıqlarından ayrı səviyyədə təcrid etmək ətrafında cəmlənmişdir.
Qalın JAR faylının əsas hissəsini təşkil edən asılılıq təbəqəsi yalnız bir dəfə endirilir və host sistemində keşlənir.
Proqram yeniləmələri və konteyner planlaşdırması zamanı tətbiqin yalnız nazik təbəqəsi çəkilir, bu diaqramda göstərildiyi kimi:
Növbəti bölmələrdə Spring Boot tətbiqi üçün bu optimallaşdırılmış şəkillərin necə yaradılacağına baxacağıq.
Buildpack ilə Spring Boot Tətbiqi üçün Optimallaşdırılmış Konteyner Şəkilinin qurulması
Spring Boot 2.3 qalın JAR faylının hissələrini ayrı-ayrı təbəqələrə çıxararaq təbəqələşdirməni dəstəkləyir. Qatlama xüsusiyyəti defolt olaraq qeyri-aktivdir və Spring Boot Maven plaginindən istifadə edərək açıq şəkildə aktivləşdirilməlidir:
Yaranan şəkildəki təbəqələri görmək üçün Dive-i işə salsaq, görərik ki, tətbiq təbəqəsi (qırmızı ilə dairəvi) qalın JAR formatından istifadə etdiyimizlə müqayisədə kilobayt diapazonunda çox kiçikdir:
Docker ilə Spring Boot Tətbiqi üçün Optimallaşdırılmış Konteyner Şəkilinin qurulması
Maven və ya Gradle plaginindən istifadə etmək əvəzinə, Docker faylı ilə qatlı Docker JAR şəkli də yarada bilərik.
Docker-dən istifadə etdikdə, təbəqələri çıxarmaq və onları son görüntüyə köçürmək üçün əlavə iki addım atmalıyıq.
Qatlaşdırma aktivləşdirilmiş Maven ilə tikildikdən sonra yaranan JAR-ın məzmunu belə görünəcək:
Çıxış adlı əlavə JAR göstərilir spring-boot-jarmode-layertoolsи layersfle.idxfayl. Bu əlavə JAR faylı növbəti hissədə təsvir olunduğu kimi təbəqələşdirmə imkanlarını təmin edir.
Ayrı-ayrı təbəqələrdən asılılıqları çıxarın
Laylı JAR-dan təbəqələrə baxmaq və çıxarmaq üçün biz sistem xassəsindən istifadə edirik -Djarmode=layertoolsbaşlanğıc üçün spring-boot-jarmode-layertoolsƏrizə əvəzinə JAR:
Bu əmri yerinə yetirmək mövcud əmr seçimlərini ehtiva edən bir nəticə çıxarır:
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
Çıxış əmrləri göstərir list, extractи helpс helpstandart olun. ilə əmri icra edək listseçim:
java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list
Biz təbəqələr kimi əlavə edilə bilən asılılıqların siyahısını görürük.
Defolt olaraq qatlar:
Qat adı
Məzmun
dependencies
versiyasında SNAPSHOT olmayan istənilən asılılıq
spring-boot-loader
JAR yükləyici sinifləri
snapshot-dependencies
versiyasında SNAPSHOT olan istənilən asılılıq
application
tətbiq sinifləri və resursları
Qatlar müəyyən edilir layers.idxfaylı Docker şəklinə əlavə edilməli olan ardıcıllıqla. Dəyişmədiyi üçün bu təbəqələr ilk gətirmədən sonra hostda keşlənir. Yalnız yenilənmiş tətbiq təbəqəsi hosta endirilir ki, bu da azaldılmış ölçüyə görə daha sürətli olur .
Ayrı-ayrı təbəqələrə çıxarılan asılılıqlarla təsvirin qurulması
adlı metoddan istifadə edərək son şəkli iki addımda quracağıq çoxmərhələli montaj . Birinci mərhələdə biz asılılıqları çıxaracağıq, ikinci mərhələdə isə çıxarılan asılılıqları finala köçürəcəyik.
Çoxmərhələli quruluş üçün Dockerfaylımızı dəyişdirək:
# 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"]
Bu konfiqurasiyanı ayrı bir faylda saxlayırıq - Dockerfile2.
Komandadan istifadə edərək Docker şəklini qururuq:
docker build -f Dockerfile2 -t usersignup:v1 .
Bu əmri yerinə yetirdikdən sonra aşağıdakı nəticəni alırıq:
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 şəklinin şəkil identifikatoru ilə yaradıldığını və sonra etiketləndiyini görə bilərik.
Nəhayət, yaradılan Docker təsvirinin içindəki təbəqələri yoxlamaq üçün Dive əmrini əvvəlki kimi icra edirik. Dive əmrinə giriş olaraq şəkil identifikatoru və ya etiket təqdim edə bilərik:
dive userssignup:v1
Çıxışdan göründüyü kimi, tətbiqi ehtiva edən təbəqə indi cəmi 11 KB-dır və asılılıqlar ayrı-ayrı təbəqələrdə yaddaşda saxlanılır.
Ayrı-ayrı təbəqələrdə daxili asılılıqları çıxarın
İstənilən fərdi asılılığımızı tətbiqdə bəyan etməklə onları proqramla qablaşdırmaq əvəzinə ayrı bir təbəqəyə çıxararaq tətbiq təbəqəsinin ölçüsünü daha da azalda bilərik. ymladlı oxşar fayl layers.idx:
Bu faylda layers.idxadlı xüsusi asılılıq əlavə etdik, io.myorgpaylaşılan depodan əldə edilən təşkilat asılılıqlarını ehtiva edir.
Buraxılış
Bu yazıda biz birbaşa mənbədən konteyner şəkli yaratmaq üçün Cloud-Native Buildpacks-dən istifadə etməyə baxdıq. Bu, adi şəkildə konteyner təsviri yaratmaq üçün Docker-dən istifadəyə alternativdir: əvvəlcə qalın icra edilə bilən JAR faylı yaradılır və sonra Dockerfile-də təlimatları təyin etməklə konteyner şəklinə qablaşdırılır.
Asılılıqları hostda keşlənmiş ayrı-ayrı təbəqələrə çıxaran və konteynerin icra mühərriklərində planlaşdırma zamanı nazik tətbiq təbəqəsi yüklənən təbəqə xüsusiyyətini daxil etməklə konteynerimizi optimallaşdırmağa da baxdıq.
Məqalədə istifadə olunan bütün mənbə kodunu burada tapa bilərsiniz Github .
Komanda Referansı
Tez istinad üçün bu məqalədə istifadə etdiyimiz əmrlərin xülasəsi budur.
Asılılıq qatlarına baxın. Tətbiq jar faylını yaratmazdan əvvəl, spring-boot-maven-plugin-də təbəqələşdirmə funksiyasının aktiv olduğundan əmin olun:
java -Djarmode=layertools -jar application.jar list
Asılılıq təbəqələrini çıxarın. Tətbiq jar faylını yaratmazdan əvvəl, spring-boot-maven-plugin-də təbəqələşdirmə funksiyasının aktiv olduğundan əmin olun: