Контейнерҳо ба воситаи бартарии бастабандии барнома бо тамоми вобастагии нармафзор ва системаи оператсионии он ва интиқоли онҳо ба муҳитҳои гуногун табдил ёфтаанд.
Ин мақола роҳҳои гуногуни контейнер кардани замимаи Spring Boot-ро дар бар мегирад:
- сохтани тасвири Docker бо истифода аз файли Docker,
- сохтани тасвири OCI аз манбаъ бо истифода аз Cloud-Native Buildpack,
- ва оптимизатсияи тасвири вақти корӣ тавассути ҷудо кардани қисмҳои JAR ба қабатҳои гуногун бо истифода аз абзорҳои бисёрсатҳа.
Намунаи код
Ин мақола бо мисоли коди корӣ ҳамроҳ карда мешавад
Терминологияи контейнер
Мо бо истилоҳоти контейнерӣ, ки дар мақола истифода шудааст, оғоз мекунем:
- Тасвири контейнер: файли формати мушаххас. Мо замимаи худро ба тасвири контейнер табдил медиҳем, ки воситаи сохтани асбобро иҷро мекунад.
- Контейнер: Намунаи иҷрошавандаи тасвири контейнер.
- Муҳаррики контейнер: Раванди демон, ки барои идора кардани контейнер масъул аст.
- Хости контейнер: Компютери асосӣ, ки дар он муҳаррики контейнер кор мекунад.
- Феҳристи контейнерҳо: Ҷойгоҳи умумӣ барои интишор ва паҳн кардани тасвири контейнер истифода мешавад.
- Стандарти OCI:
Ташаббуси контейнери кушод (OCI) сохтори сабук ва кушодаи идоракунӣ мебошад, ки дар доираи Бунёди Linux ташкил шудааст. Мушаххасоти тасвири OCI стандартҳои саноатиро барои тасвири контейнер ва форматҳои вақти корӣ муайян мекунад, то кафолат диҳад, ки ҳама муҳаррикҳои контейнер метавонанд тасвирҳои контейнериро, ки аз ҷониби ҳама асбоби сохтмон сохта шудаанд, иҷро кунанд.
Барои контейнер кардани барнома, мо замимаи худро дар тасвири контейнер мепӯшем ва он тасвирро дар феҳристи муштарак нашр мекунем. Вақти иҷроиши контейнер ин тасвирро аз реестр бармегардонад, онро мекушояд ва барномаро дар дохили он иҷро мекунад.
Версияи 2.3-и Spring Boot плагинҳоро барои эҷоди тасвирҳои OCI таъмин мекунад.
Сохтани тасвири контейнер бо роҳи анъанавӣ
Эҷоди тасвирҳои Docker барои замимаҳои Spring Boot бо илова кардани чанд дастур ба файли Docker хеле осон аст.
Мо аввал файли иҷрошавандаи JAR эҷод мекунем ва ҳамчун як қисми дастурҳои файли Docker, пас аз татбиқи танзимоти зарурӣ файли иҷрошавандаи JAR-ро дар болои тасвири асосии JRE нусхабардорӣ мекунем.
Биёед барномаи баҳори худро дар он созем web
, lombok
и actuator
. Мо инчунин як контролери истироҳатро барои таъмин кардани API илова мекунем GET
усул.
Эҷоди файли Docker
Пас аз он мо ин барномаро бо илова кардан контейнер мекунем 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 бо истифода аз Buildpack тасвирҳои OCI-ро аз манбаъ месозад. Тасвирҳо бо истифода аз он сохта мешаванд 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
ҳадафҳо барои эҷоди барнома ва эҷоди тасвири контейнер. Мо дар айни замон ягон файли Docker-ро истифода намебарем.
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 Boot
Формулаи оптимизатсия ба ҷудо кардани барнома дар сатҳи алоҳида аз вобастагии Spring Framework нигаронида шудааст.
Қабати вобастагӣ, ки қисми асосии файли ғафси JAR-ро ташкил медиҳад, танҳо як маротиба зеркашӣ карда мешавад ва дар системаи ҳост кэш карда мешавад.
Ҳангоми навсозии барномаҳо ва банақшагирии контейнер танҳо як қабати тунуки барнома кашида мешавад. чунон ки дар ин диаграмма нишон дода шудааст:
Дар бахшҳои зерин мо дида мебароем, ки чӣ гуна ин тасвирҳои оптимизатсияшуда барои барномаи 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 дар диапазони килобайт хеле хурдтар аст:
Эҷоди тасвири оптимизатсияшудаи контейнер барои замимаи баҳорӣ бо истифода аз 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 КБ аст ва вобастагӣ дар қабатҳои алоҳида кэш карда мешаванд.
Истихроҷи вобастагии дохилӣ аз қабатҳои инфиродӣ
Мо метавонем минбаъд андозаи сатҳи барномаро тавассути истихроҷи ҳама гуна вобастагии фармоишии мо ба сатҳи алоҳида ба ҷои бастабандии онҳо бо замима тавассути эълон кардани онҳо кам кунем. 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