Օպտիմիզացված Docker պատկերների ստեղծում Spring Boot հավելվածի համար

Կոնտեյներները դարձել են հավելվածները ծրագրային և օպերացիոն համակարգերի բոլոր կախվածություններով փաթեթավորելու և այնուհետև դրանք տարբեր միջավայրեր հասցնելու նախընտրելի միջոցը:

Այս հոդվածը ներառում է Spring Boot հավելվածի կոնտեյներացման տարբեր եղանակներ.

  • Docker ֆայլի միջոցով ստեղծելով Docker պատկեր,
  • ստեղծելով OCI պատկեր աղբյուրից՝ օգտագործելով Cloud-Native Buildpack,
  • և գործարկման ժամանակի պատկերի օպտիմիզացում՝ JAR-ի մասերը տարբեր շերտերի բաժանելով՝ օգտագործելով բազմաշերտ գործիքներ:

 Կոդի օրինակ

Այս հոդվածը կցվում է աշխատանքային կոդի օրինակով GitHub-ում .

Կոնտեյների տերմինաբանություն

Մենք կսկսենք հոդվածում օգտագործված կոնտեյների տերմինաբանությունից.

  • Կոնտեյների պատկեր: որոշակի ձևաչափի ֆայլ: Մենք մեր հավելվածը կվերածենք կոնտեյների պատկերի` գործարկելով build գործիքը:
  • ԲեռնարկղԿոնտեյների պատկերի գործարկվող օրինակ:
  • Բեռնարկղային շարժիչԴեյմոն գործընթաց, որը պատասխանատու է կոնտեյների գործարկման համար:
  • Կոնտեյների հյուրընկալողՀյուրընկալող համակարգիչ, որի վրա աշխատում է կոնտեյների շարժիչը:
  • Կոնտեյների ռեեստրԸնդհանուր տեղադրությունը, որն օգտագործվում է կոնտեյների պատկերը հրապարակելու և տարածելու համար:
  • OCI ստանդարտOpen Container Initiative (OCI) թեթև, բաց կառավարման կառույց է, որը ձևավորվել է Linux հիմնադրամի շրջանակներում: OCI Image Specification-ը սահմանում է արդյունաբերական ստանդարտներ կոնտեյների պատկերի և գործարկման ժամանակի ձևաչափերի համար՝ ապահովելու համար, որ բոլոր կոնտեյների շարժիչները կարող են գործարկել կոնտեյների պատկերները, որոնք ստեղծված են ցանկացած կառուցման գործիքի միջոցով:

Հավելվածը կոնտեյներացնելու համար մենք մեր հավելվածը փաթաթում ենք կոնտեյների պատկերով և հրապարակում այդ պատկերը ընդհանուր ռեեստրում: Կոնտեյների գործարկման ժամանակը վերցնում է այս պատկերը ռեեստրից, ապափաթեթավորում է այն և գործարկում հավելվածը դրա ներսում:

Spring Boot-ի 2.3 տարբերակը տրամադրում է պլագիններ OCI պատկերներ ստեղծելու համար:

դոկեր Սա ամենահաճախ օգտագործվող կոնտեյների իրականացումն է, և մենք օգտագործում ենք Docker-ը մեր օրինակներում, ուստի այս հոդվածի բոլոր հետագա կոնտեյների հղումները վերաբերելու են Docker-ին:

Կոնտեյների պատկերի կառուցում ավանդական եղանակով

Spring Boot հավելվածների համար Docker պատկերների ստեղծումը շատ հեշտ է՝ մի քանի հրահանգներ ավելացնելով Docker ֆայլին:

Մենք նախ ստեղծում ենք գործարկվող JAR ֆայլ և որպես Docker ֆայլի հրահանգների մաս, անհրաժեշտ կարգավորումները կիրառելուց հետո պատճենում ենք գործարկվող JAR ֆայլը բազային JRE պատկերի վերևում:

Եկեք ստեղծենք մեր Գարուն հավելվածը 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 ֆայլ: Մենք պետք է այս գործարկվող 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 հրամանի արդյունքի մի մասը. 

Օպտիմիզացված Docker պատկերների ստեղծում Spring Boot հավելվածի համար

Ինչպես տեսնում ենք, կիրառական շերտը կազմում է պատկերի չափի զգալի մասը: Մենք ցանկանում ենք նվազեցնել այս շերտի չափը հետևյալ բաժիններում՝ որպես մեր օպտիմալացման մաս:

Buildpack-ի միջոցով կոնտեյների պատկերի ստեղծում

Մոնտաժային փաթեթներ (Buildpacks) ընդհանուր տերմին է, որն օգտագործվում է տարբեր Պլատֆորմ որպես ծառայություն (PAAS) առաջարկների կողմից՝ աղբյուրի կոդից կոնտեյների պատկեր ստեղծելու համար: Այն գործարկվել է Heroku-ի կողմից 2011 թվականին և այնուհետև ընդունվել է Cloud Foundry-ի, Google App Engine-ի, Gitlab-ի, Knative-ի և մի քանի այլ կողմից:

Օպտիմիզացված Docker պատկերների ստեղծում Spring Boot հավելվածի համար

Ամպային կառուցման փաթեթների առավելությունները

Պատկերներ ստեղծելու համար Buildpack-ի օգտագործման հիմնական առավելություններից մեկն այն է Պատկերի կազմաձևման փոփոխությունները կարող են կառավարվել կենտրոնական (շինարար) և տարածվել բոլոր հավելվածներում՝ օգտագործելով Builder:

Կառուցման փաթեթները սերտորեն կապված էին հարթակի հետ: Cloud-Native Buildpacks-ը ապահովում է ստանդարտացում բոլոր հարթակներում՝ աջակցելով OCI պատկերի ձևաչափին, որն ապահովում է, որ պատկերը կարող է գործարկվել Docker շարժիչով:

Օգտագործելով Spring Boot հավելվածը

Spring Boot plugin-ը կառուցում է 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-pluginpom.xml-ում:

      <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>2.5.2</version>
      </plugin>

Հաջորդը, մենք գործարկում ենք Jib plugin-ը, օգտագործելով 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-ի օգտագործումը «ճարպ ՋԱՐ» մեջ որպես լռելյայն փաթեթավորման ձևաչափ: Երբ մենք նայում ենք հաստ JAR-ին, տեսնում ենք, որ հավելվածը կազմում է ամբողջ JAR-ի շատ փոքր մասը: Սա այն հատվածն է, որն ամենից հաճախ փոխվում է: Մնացածը բաղկացած է Spring Framework-ի կախվածություններից:

Օպտիմիզացման բանաձևը կենտրոնանում է հավելվածը Spring Framework-ի կախվածությունից առանձին մակարդակով մեկուսացնելու շուրջ:

Կախվածության շերտը, որը կազմում է հաստ JAR ֆայլի մեծ մասը, ներբեռնվում է միայն մեկ անգամ և պահվում է հյուրընկալող համակարգում:

Հավելվածի միայն բարակ շերտն է քաշվում հավելվածի թարմացումների և բեռնարկղերի պլանավորման ժամանակ: ինչպես ցույց է տրված այս դիագրամում.

Օպտիմիզացված Docker պատկերների ստեղծում Spring Boot հավելվածի համար

Հաջորդ բաժիններում մենք կանդրադառնանք, թե ինչպես ստեղծել այս օպտիմիզացված պատկերները 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-imageMaven թիրախը կոնտեյների պատկեր ստեղծելու համար.

mvn spring-boot:build-image

Եթե ​​մենք գործարկենք Dive-ը, որպեսզի տեսնենք շերտերը ստացված պատկերում, մենք կարող ենք տեսնել, որ կիրառական շերտը (կարմիրով ուրվագծված) շատ ավելի փոքր է կիլոբայթային տիրույթում, համեմատած այն, ինչ մենք ստացել ենք հաստ JAR ձևաչափով.

Օպտիմիզացված Docker պատկերների ստեղծում Spring Boot հավելվածի համար

Օպտիմիզացված կոնտեյների պատկերի ստեղծում Spring Boot հավելվածի համար Docker-ի միջոցով

Maven կամ Gradle պլագին օգտագործելու փոխարեն մենք կարող ենք նաև Docker ֆայլով ստեղծել շերտավորված Docker JAR պատկեր։

Երբ մենք օգտագործում ենք 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-layertoolsJAR հավելվածի փոխարեն.

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 Loader դասեր

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 ԿԲ է, և կախվածությունները պահվում են առանձին շերտերում: 

Օպտիմիզացված Docker պատկերների ստեղծում Spring Boot հավելվածի համար

Առանձին շերտերից ներքին կախվածությունների արդյունահանում

Մենք կարող ենք էլ ավելի նվազեցնել հավելվածի մակարդակի չափը՝ հանելով մեր սովորական կախվածություններից որևէ մեկը առանձին մակարդակի մեջ՝ դրանք հավելվածով փաթեթավորելու փոխարեն՝ դրանք հայտարարելով 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 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>

Source: www.habr.com