Хаврын ачаалах програмын оновчтой Docker зургуудыг бий болгох

Контейнер нь программ хангамж, үйлдлийн системийн бүх хамаарал бүхий программыг савлаж, дараа нь өөр өөр орчинд хүргэх хамгийн тохиромжтой хэрэгсэл болжээ.

Энэ нийтлэлд Spring Boot програмыг хадгалах янз бүрийн аргуудыг багтаасан болно.

  • Docker файл ашиглан Docker дүрс үүсгэх,
  • Cloud-Native Buildpack ашиглан эх сурвалжаас OCI дүрс үүсгэх,
  • олон шатлалт хэрэглүүр ашиглан JAR-ийн хэсгүүдийг өөр өөр давхаргад хуваах замаар ажиллах хугацааны дүрсийг оновчтой болгох.

 Жишээ код

Энэ нийтлэлийг ажлын кодын жишээ дагалдуулсан болно GitHub дээр .

Контейнерийн нэр томъёо

Бид нийтлэлд ашигласан контейнерийн нэр томъёоноос эхэлнэ:

  • Контейнерийн зураг: тодорхой форматтай файл. Бид бүтээх хэрэгслийг ажиллуулснаар програмаа контейнер дүрс болгон хувиргах болно.
  • Контейнер: Контейнерын зургийн гүйцэтгэх жишээ.
  • Контейнер хөдөлгүүр: Контейнерийг ажиллуулах үүрэгтэй демон процесс.
  • Контейнер хост: Контейнерийн хөдөлгүүр ажилладаг үндсэн компьютер.
  • Контейнерийн бүртгэл: Контейнерийн зургийг нийтлэх, түгээхэд ашигладаг ерөнхий байршил.
  • OCI стандартНээлттэй контейнер санаачлага (OCI) Линукс сангийн хүрээнд бий болсон хөнгөн, нээлттэй засаглалын бүтэц юм. OCI Зургийн тодорхойлолт нь бүх контейнерийн хөдөлгүүрүүд ямар ч бүтээх хэрэгслээр үүсгэсэн контейнерийн зургийг ажиллуулж чаддаг байхын тулд контейнерийн зураг болон ажиллах цагийн форматын салбарын стандартыг тодорхойлдог.

Аппликейшныг хадгалахын тулд бид програмаа контейнерийн зурагт боож, тэр зургийг хуваалцсан бүртгэлд нийтэлдэг. Контейнерийн ажиллах хугацаа нь энэ зургийг бүртгэлээс авч, задалж, доторх програмыг ажиллуулдаг.

Spring Boot-ийн 2.3 хувилбар нь OCI дүрс үүсгэх нэмэлт өргөтгөлүүдийг өгдөг.

Docker нь хамгийн түгээмэл хэрэглэгддэг контейнерийн хэрэгжилт бөгөөд бид жишээндээ Docker ашигладаг тул энэ нийтлэл дэх бүх контейнерийн лавлагааг Docker-д дурдах болно.

Контейнерийн зургийг уламжлалт аргаар бүтээх

Docker файлд цөөн хэдэн зааврыг нэмснээр Spring Boot програмуудад зориулсан Docker дүрс үүсгэх нь маш хялбар юм.

Бид эхлээд гүйцэтгэх боломжтой JAR файлыг үүсгэж, Docker файлын зааврын нэг хэсэг болгон шаардлагатай тохиргоог хийсний дараа үндсэн JRE зургийн дээд талд гүйцэтгэх JAR файлыг хуулна.

Хаврын аппликейшнээ үүсгэцгээе Spring Initializr хамаарал бүхий weblombokи 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 файлыг үүсгэдэг. Бид Docker хөдөлгүүр дээр ажиллахын тулд энэхүү гүйцэтгэгдэх JAR-г 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 командын гаралтын хэсэг энд байна: 

Хаврын ачаалах програмын оновчтой Docker зургуудыг бий болгох

Бидний харж байгаагаар хэрэглээний давхарга нь зургийн хэмжээний нэлээд хэсгийг бүрдүүлдэг. Бид оновчлолынхоо нэг хэсэг болгон дараах хэсгүүдэд энэ давхаргын хэмжээг багасгахыг хүсч байна.

Buildpack ашиглан контейнерийн зураг үүсгэх

Угсралтын багцууд (Барилгын багцууд) нь платформ as a Service (PAAS)-ын төрөл бүрийн саналуудад эх кодоос контейнер дүрс үүсгэхэд хэрэглэгддэг ерөнхий нэр томъёо юм. Үүнийг Heroku 2011 онд эхлүүлсэн бөгөөд түүнээс хойш Cloud Foundry, Google App Engine, Gitlab, Knative болон бусад хэд хэдэн компани нэвтрүүлсэн.

Хаврын ачаалах програмын оновчтой Docker зургуудыг бий болгох

Үүл бүтээх багцын давуу тал

Зураг бүтээхдээ 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програм үүсгэх, контейнер дүрсийг бүтээх зорилго. Бид одоогоор ямар ч Dockerfile ашиглаагүй байна.

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-pluginpom.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 дамжуулах хоолойд бүтээх хугацаа урт болно.
  • Аюулгүй байдал: Том зургууд нь эмзэг байдлын хувьд илүү том талбайтай байдаг.

Докерын зураг нь давхаргын стекээс бүрдэх бөгөөд давхарга бүр нь манай Dockerfile дахь зааврыг илэрхийлдэг. Давхарга бүр нь доод давхаргын өөрчлөлтийн гурвалжин хэсгийг илэрхийлдэг. Бид бүртгэлээс Docker дүрсийг татахад давхаргад нь татаж аваад хост дээр хадгалагдана.

Spring Boot-ийн хэрэглээ "тарган ваар" дотор анхдагч савлагааны форматаар. Зузаан JAR-г харахад уг програм нь бүх JAR-ийн маш бага хэсгийг бүрдүүлдэг болохыг бид харж байна. Энэ бол хамгийн их өөрчлөгддөг хэсэг юм. Үлдсэн хэсэг нь Spring Framework-ийн хамаарлаас бүрдэнэ.

Оновчлолын томъёо нь програмыг Spring Framework-ийн хамаарлаас тусдаа түвшинд тусгаарлахад чиглэдэг.

Зузаан JAR файлын дийлэнх хэсгийг бүрдүүлдэг хамаарлын давхаргыг зөвхөн нэг удаа татаж аваад хост систем дээр хадгалдаг.

Аппликешныг шинэчлэх болон савны хуваарь гаргах үед програмын зөвхөн нимгэн давхаргыг татдаг. Энэ диаграммд үзүүлсэн шиг:

Хаврын ачаалах програмын оновчтой Docker зургуудыг бий болгох

Дараах хэсгүүдэд бид 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 зургуудыг бий болгох

Docker ашиглан хаврын ачаалах програмын оновчтой контейнер дүрсийг үүсгэх

Бид Maven эсвэл Gradle залгаасыг ашиглахын оронд Docker файлаар давхарласан Docker JAR дүрс үүсгэж болно.

Бид Docker-ийг ашиглахдаа давхаргыг задлах, эцсийн зураг руу хуулах хоёр нэмэлт алхам хийх хэрэгтэй.

Давхаргыг идэвхжүүлсэн Maven ашиглан бүтээсний дараа үүссэн JAR-ийн агуулга дараах байдалтай харагдана.

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

Гаралт нь тушаалуудыг харуулж байна listextractи 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 дүрс дээр нэмэх ёстой. Эдгээр давхаргууд нь өөрчлөгддөггүй тул эхний хайлт хийсний дараа хост дээр хадгалагдана. Зөвхөн шинэчлэгдсэн програмын давхаргыг хост руу татаж авдаг бөгөөд энэ нь хэмжээ багассан тул илүү хурдан байдаг .

Тусдаа давхарга болгон задалсан хамаарал бүхий зураг бүтээх

гэж нэрлэгддэг аргыг ашиглан бид хоёр үе шаттайгаар эцсийн дүрсийг бүтээх болно олон үе шаттай угсралт . Эхний алхамд бид хамаарлыг задлах ба хоёр дахь шатанд гаргаж авсан хамаарлыг эцсийн зураг руу хуулах болно.

Докер файлаа олон үе шаттай бүтээхийн тулд өөрчилье:

# 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-аар үүсгээд дараа нь тагласан болохыг харж болно.

Эцэст нь бид үүсгэсэн Docker дүрс доторх давхаргыг шалгахын тулд Dive командыг өмнөх шигээ ажиллуулна. Бид Dive командын оролт болгон зургийн ID эсвэл шошго өгч болно:

dive userssignup:v1

Гаралтаас харахад програмыг агуулсан давхарга нь одоо ердөө 11 KB бөгөөд хамаарал нь тусдаа давхаргад хадгалагдсан байна. 

Хаврын ачаалах програмын оновчтой Docker зургуудыг бий болгох

Бие даасан давхарга дээрх дотоод хамаарлыг задлах

Бид өөрсдийн дурын хамаарлыг програмын хамт багцлахын оронд тус тусад нь гаргаж авснаар хэрэглээний түвшний хэмжээг багасгаж болно. 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 файлд зааврыг зааж өгөх замаар контейнерийн дүрс болгон савлана.

Бид мөн хост дээр хадгалагдсан хамаарлыг салангид давхаргууд болгон татах давхаргын функцийг идэвхжүүлж, контейнерын гүйцэтгэх хөдөлгүүрт хуваарийн дагуу програмын нимгэн давхаргыг ачаалах замаар контейнерээ оновчтой болгох талаар авч үзсэн.

Та нийтлэлд ашигласан бүх эх кодыг эндээс олж болно Github .

Тушаалын лавлагаа

Энэ нийтлэлд ашигласан командуудын товч тоймыг энд оруулав.

Контекст цэвэрлэх:

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>

Эх сурвалж: www.habr.com