Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Имали смо 2 Π²Ρ€Π΅Ρ›Π΅ Ρ‚Ρ€Π°Π²Π΅, 75 мСскалин Ρ‚Π°Π±Π»Π΅Ρ‚Π° ΡƒΠ½ΠΈΠΊ ΠΎΠΊΡ€ΡƒΠΆΠ΅ΡšΠ΅, Π΄ΠΎΡ†ΠΊΠ΅Ρ€ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΡ˜ΡƒΠΌ ΠΈ Π·Π°Π΄Π°Ρ‚Π°ΠΊ Π΄Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°ΠΌΠΎ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄Π΅ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π°.

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Π£ΠŸΠ”:
ΠŸΠΈΡ‚Π°ΡšΠ΅: Π§Π΅ΠΌΡƒ свС ΠΎΠ²ΠΎ?
ΠžΠ΄Π³ΠΎΠ²ΠΎΡ€: Π’Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅ ΡƒΡ‡ΠΈΡ‚Π°Π²Π°ΡšΠ° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π° (НЕ користи басх, скриптС су Π΄Π°Ρ‚Π΅ Ρƒ ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π½Π΅ сврхС). ΠžΠ΄Π»ΡƒΡ‡Π΅Π½ΠΎ јС Π΄Π° сС Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚ Π½Π΅ користи Π·Π° смањСњС Π΄ΠΎΠ΄Π°Ρ‚Π½ΠΈΡ… слојСва (Ρƒ Ρ€Π°Π·ΡƒΠΌΠ½ΠΈΠΌ Π³Ρ€Π°Π½ΠΈΡ†Π°ΠΌΠ°) ΠΈ, сходно Ρ‚ΠΎΠΌΠ΅, Π΅ΠΌΡƒΠ»Π°Ρ†ΠΈΡ˜Ρƒ Π²Π΅Ρ›Π΅Π³ ΠΎΠΏΡ‚Π΅Ρ€Π΅Ρ›Π΅ΡšΠ°. Као Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Ρ‚ΠΎΠ³Π°, сва систСмска кашњСња Π”ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° су ΡƒΠΊΠ»ΠΎΡšΠ΅Π½Π°. Π”ΠΎΠ±ΠΈΠ»ΠΈ смо Ρ€Π΅Π»Π°Ρ‚ΠΈΠ²Π½ΠΎ чисто ΠΎΠΏΡ‚Π΅Ρ€Π΅Ρ›Π΅ΡšΠ΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Ρƒ.
Π§Π»Π°Π½Π°ΠΊ јС користио ГНУ Π²Π΅Ρ€Π·ΠΈΡ˜Π΅ Π°Π»Π°Ρ‚Π°.

ΠŸΡ€Π²ΠΎ, Ρ…Π°Ρ˜Π΄Π΅ Π΄Π° схватимо ΡˆΡ‚Π° ΠΎΠ²Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Π΅ Ρ€Π°Π΄Π΅.

Π”Π°ΠΊΠ»Π΅, Π·Π° ΡˆΡ‚Π° сС користи Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π»? ΠŸΡ€Π΅ΠΌΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°:

β€žΠ˜Π·Π²ΡƒΡ†ΠΈΡ‚Π΅ слику ΠΈΠ»ΠΈ ΡΠΏΡ€Π΅ΠΌΠΈΡˆΡ‚Π΅ ΠΈΠ· Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°β€œ.

Π’Π°ΠΌΠΎ Ρ‚Π°ΠΊΠΎΡ’Π΅ Π½Π°Π»Π°Π·ΠΈΠΌΠΎ Π²Π΅Π·Ρƒ Π΄ΠΎ Ρ€Π°Π·ΡƒΠΌΠ΅Ρ˜Ρƒ сликС, ΠΊΠΎΠ½Ρ‚Π΅Ρ˜Π½Π΅Ρ€Π΅ ΠΈ Π΄Ρ€Π°Ρ˜Π²Π΅Ρ€Π΅ Π·Π° ΡΠΊΠ»Π°Π΄ΠΈΡˆΡ‚Π΅ΡšΠ΅.

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

ОдавдС ΠΌΠΎΠΆΠ΅ΠΌΠΎ Ρ€Π°Π·ΡƒΠΌΠ΅Ρ‚ΠΈ Π΄Π° јС Π΄ΠΎΡ†ΠΊΠ΅Ρ€ слика скуп ΠΎΠ΄Ρ€Π΅Ρ’Π΅Π½ΠΈΡ… слојСва који садрТС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ˜Π΅ ΠΎ најновијим ΠΏΡ€ΠΎΠΌΠ΅Π½Π°ΠΌΠ° Π½Π° слици, ΡˆΡ‚ΠΎ јС ΠΎΡ‡ΠΈΠ³Π»Π΅Π΄Π½ΠΎ ΠΎΠ½ΠΎ ΡˆΡ‚ΠΎ Π½Π°ΠΌ јС ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ. Π‘Π»Π΅Π΄Π΅Ρ›Π΅ Π³Π»Π΅Π΄Π°ΠΌΠΎ АПИ рСгистра.

ΠΊΠ°ΠΆΠ΅ слСдСћС:

β€žΠ‘Π»ΠΈΠΊΠ°β€œ јС ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡ˜Π° ЈБОН манифСста ΠΈ ΠΏΠΎΡ˜Π΅Π΄ΠΈΠ½Π°Ρ‡Π½ΠΈΡ… Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ° слоја. ΠŸΡ€ΠΎΡ†Π΅Ρ ΠΏΠΎΠ²Π»Π°Ρ‡Π΅ΡšΠ° > сликС сС ΡƒΡΡ€Π΅Π΄ΡΡ€Π΅Ρ’ΡƒΡ˜Π΅ Π½Π° ΠΏΡ€Π΅ΡƒΠ·ΠΈΠΌΠ°ΡšΠ΅ ΠΎΠ²Π΅ Π΄Π²Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅.β€œ

Π”Π°ΠΊΠ»Π΅, ΠΏΡ€Π²ΠΈ ΠΊΠΎΡ€Π°ΠΊ ΠΏΡ€Π΅ΠΌΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜ΠΈ јС β€žΠ˜Π·Π²Π»Π°Ρ‡Π΅ΡšΠ΅ манифСста сликС".

Наравно, Π½Π΅Ρ›Π΅ΠΌΠΎ Π³Π° снимати, Π°Π»ΠΈ су Π½Π°ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈ ΠΏΠΎΠ΄Π°Ρ†ΠΈ ΠΈΠ· њСга. Π‘Π»Π΅Π΄ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π°Ρ…Ρ‚Π΅Π²Π°: GET /v2/{name}/manifests/{reference}

β€žΠΠ°Π·ΠΈΠ² ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Π°Ρ€ Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΡƒΡ˜Ρƒ слику ΠΈ ΠΎΠ±Π°Π²Π΅Π·Π½ΠΈ су. Π Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†Π° ΠΌΠΎΠΆΠ΅ Π΄Π° садрТи ΠΎΠ·Π½Π°ΠΊΡƒ ΠΈΠ»ΠΈ саТСтак.β€œ

НашС Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΡΠΏΡ€Π΅ΠΌΠΈΡˆΡ‚Π΅ јС распорСђСно Π»ΠΎΠΊΠ°Π»Π½ΠΎ, Ρ…Π°Ρ˜Π΄Π΅ Π΄Π° ΠΏΠΎΠΊΡƒΡˆΠ°ΠΌΠΎ Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠΎ Π·Π°Ρ…Ρ‚Π΅Π²:

curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/manifests/1.1.1" -H "header_if_needed"

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Као ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€ добијамо јсон ΠΎΠ΄ којСг нас Ρ‚Ρ€Π΅Π½ΡƒΡ‚Π½ΠΎ Π·Π°Π½ΠΈΠΌΠ°Ρ˜Ρƒ само линијС спасавања, односно ΡšΠΈΡ…ΠΎΠ²ΠΈ Ρ…Π΅ΡˆΠΎΠ²ΠΈ. Када ΠΈΡ… ΠΏΡ€ΠΈΠΌΠΈΠΌΠΎ, ΠΌΠΎΠΆΠ΅ΠΌΠΎ Π΄Π° ΠΏΡ€ΠΎΡ’Π΅ΠΌΠΎ ΠΊΡ€ΠΎΠ· сваки ΠΈ ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠΎ слСдСћи Π·Π°Ρ…Ρ‚Π΅Π²: β€žΠ“Π•Π’ /Π²2/{Π½Π°ΠΌΠ΅}/блобс/{дигСст}β€œ

β€žΠŸΡ€ΠΈΡΡ‚ΡƒΠΏ ΡΠ»ΠΎΡ˜Ρƒ Ρ›Π΅ Π±ΠΈΡ‚ΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ ΠΈΠΌΠ΅Π½ΠΎΠΌ ΡΠΏΡ€Π΅ΠΌΠΈΡˆΡ‚Π°, Π°Π»ΠΈ јС Ρ˜Π΅Π΄ΠΈΠ½ΡΡ‚Π²Π΅Π½ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠΎΠ²Π°Π½ Ρƒ рСгистру ΠΏΠΎΠΌΠΎΡ›Ρƒ саТСтка.β€œ

дигСст Ρƒ ΠΎΠ²ΠΎΠΌ ΡΠ»ΡƒΡ‡Π°Ρ˜Ρƒ јС Ρ…Π΅Ρˆ који смо ΠΏΡ€ΠΈΠΌΠΈΠ»ΠΈ.

Π₯ајдС Π΄Π° ΠΏΠΎΠΊΡƒΡˆΠ°ΠΌΠΎ

curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/blobs/sha256:f972d139738dfcd1519fd2461815651336ee25a8b54c358834c50af094bb262f" -H "header_if_needed" --output firstLayer

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Π₯ајдС Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠΎ ΠΊΠ°ΠΊΠ°Π² смо Ρ„Π°Ρ˜Π» ΠΊΠΎΠ½Π°Ρ‡Π½ΠΎ Π΄ΠΎΠ±ΠΈΠ»ΠΈ ΠΊΠ°ΠΎ ΠΏΡ€Π²ΠΈ спас.

file firstLayer

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

ΠΎΠ½Π΅. шинС су Ρ‚Π°Ρ€ Π°Ρ€Ρ…ΠΈΠ²Π΅, Ρ€Π°ΡΠΏΠ°ΠΊΡƒΡ˜ΡƒΡ›ΠΈ ΠΈΡ… ΠΎΠ΄Π³ΠΎΠ²Π°Ρ€Π°Ρ˜ΡƒΡ›ΠΈΠΌ рСдослСдом Π΄ΠΎΠ±ΠΈΡ›Π΅ΠΌΠΎ ΡΠ°Π΄Ρ€ΠΆΠ°Ρ˜ сликС.

Π₯ајдС Π΄Π° напишСмо ΠΌΠ°Π»Ρƒ басх скрипту ΠΊΠ°ΠΊΠΎ Π±ΠΈ свС ΠΎΠ²ΠΎ ΠΌΠΎΠ³Π»ΠΎ Π΄Π° сС Π°ΡƒΡ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΡƒΡ˜Π΅

#!/bin/bash -eu

downloadDir=$1
# url as http://localhost:8081/link/to/docker/registry
url=$2
imageName=$3
tag=$4

# array of layers
layers=($(curl -s -X GET "$url/v2/$imageName/manifests/$tag" | grep -oP '(?<=blobSum" : ").+(?=")'))

# download each layer from array
for layer in "${layers[@]}"; do
    echo "Downloading ${layer}"
    curl -v -X GET "$url/v2/$imageName/blobs/$layer" --output "$downloadDir/$layer.tar"
done

# find all layers, untar them and remove source .tar files
cd "$downloadDir" && find . -name "sha256:*" -exec tar xvf {} ;
rm sha256:*.tar
exit 0

Π‘Π°Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌΠΎ Π΄Π° Π³Π° ΠΏΠΎΠΊΡ€Π΅Π½Π΅ΠΌΠΎ са ΠΆΠ΅Ρ™Π΅Π½ΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠΌΠ° ΠΈ добијСмо ΡΠ°Π΄Ρ€ΠΆΠ°Ρ˜ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½Π΅ сликС

./script.sh dirName β€œhttp://localhost:8081/link/to/docker/registry” myAwesomeImage 1.0

Π”Π΅ΠΎ 2 - Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх

Ово Ρ›Π΅ Π±ΠΈΡ‚ΠΈ ΠΌΠ°Π»ΠΎ компликованијС.

ΠŸΠΎΡ‡Π½ΠΈΠΌΠΎ ΠΏΠΎΠ½ΠΎΠ²ΠΎ са Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°. Π”Π°ΠΊΠ»Π΅, Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΏΡ€Π΅ΡƒΠ·ΠΌΠ΅ΠΌΠΎ сваког Π»ΠΈΠ΄Π΅Ρ€Π°, ΠΏΡ€ΠΈΠΊΡƒΠΏΠΈΠΌΠΎ ΠΎΠ΄Π³ΠΎΠ²Π°Ρ€Π°Ρ˜ΡƒΡ›ΠΈ манифСст ΠΈ Ρ‚Π°ΠΊΠΎΡ’Π΅ Π³Π° ΠΏΡ€Π΅ΡƒΠ·ΠΌΠ΅ΠΌΠΎ. ИзглСда Ρ˜Π΅Π΄Π½ΠΎΡΡ‚Π°Π²Π½ΠΎ.

Након ΠΏΡ€ΠΎΡƒΡ‡Π°Π²Π°ΡšΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π΅, ΠΌΠΎΠΆΠ΅ΠΌΠΎ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΠΈ процСс ΠΏΡ€Π΅ΡƒΠ·ΠΈΠΌΠ°ΡšΠ° Ρƒ Π½Π΅ΠΊΠΎΠ»ΠΈΠΊΠΎ ΠΊΠΎΡ€Π°ΠΊΠ°:

  • Π˜Π½ΠΈΡ†ΠΈΡ˜Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡ˜Π° процСса – β€žΠŸΠžΠ‘Π’ /Π²2/{рСпоНамС}/блобс/уплоадс/β€œ
  • ΠžΡ‚ΠΏΡ€Π΅ΠΌΠ°ΡšΠ΅ линијС спасавања (користићСмо ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π½ΠΎ ΠΎΡ‚ΠΏΡ€Π΅ΠΌΠ°ΡšΠ΅, Ρ‚Ρ˜. ΡˆΠ°Ρ™Π΅ΠΌΠΎ сваку Π»ΠΈΠ½ΠΈΡ˜Ρƒ спаса Ρƒ Ρ†Π΅Π»ΠΈΠ½ΠΈ) - β€žΠŸΠ£Π’ /Π²2/{рСпоНамС}/блобс/уплоадс/{ΡƒΡƒΠΈΠ΄}?дигСст={дигСст}
    Π”ΡƒΠΆΠΈΠ½Π° ΡΠ°Π΄Ρ€ΠΆΠ°Ρ˜Π°: {Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Π° слоја}
    Π¦ΠΎΠ½Ρ‚Π΅Π½Ρ‚-Π’ΠΈΠΏΠ΅: Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°/ΠΎΠΊΡ‚Π΅Ρ‚-Ρ‚ΠΎΠΊ
    Π‘ΠΈΠ½Π°Ρ€Π½ΠΈ ΠΏΠΎΠ΄Π°Ρ†ΠΈ ΡΠ»ΠΎΡ˜Π°β€œ.
  • Π£Ρ‡ΠΈΡ‚Π°Π²Π°ΡšΠ΅ манифСста – β€žΠŸΠ£Π’ /Π²2/{рСпоНамС}/манифСстс/{Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†Π΅}β€œ.

Али Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜ΠΈ Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ˜Π΅ јСдан ΠΊΠΎΡ€Π°ΠΊ, Π±Π΅Π· којСг Π½ΠΈΡˆΡ‚Π° Π½Π΅Ρ›Π΅ Ρ€Π°Π΄ΠΈΡ‚ΠΈ. Π—Π° ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π½ΠΎ ΠΎΠΏΡ‚Π΅Ρ€Π΅Ρ›Π΅ΡšΠ΅, ΠΊΠ°ΠΎ ΠΈ Π·Π° Π΄Π΅Π»ΠΈΠΌΠΈΡ‡Π½ΠΎ (Ρƒ ΠΊΠΎΠΌΠ°Π΄ΠΈΠΌΠ°), ΠΏΡ€Π΅ ΡƒΡ‚ΠΎΠ²Π°Ρ€Π° шинС, ΠΌΠΎΡ€Π°Ρ‚Π΅ ΠΈΠ·Π²Ρ€ΡˆΠΈΡ‚ΠΈ ПАВЦΠ₯ Π·Π°Ρ…Ρ‚Π΅Π²:

β€žΠŸΠΠ’Π¦Π₯ /Π²2/{рСпоНамС}/блобс/уплоадс/{ΡƒΡƒΠΈΠ΄}
Π”ΡƒΠΆΠΈΠ½Π° ΡΠ°Π΄Ρ€ΠΆΠ°Ρ˜Π°: {сизС ΠΎΡ„ Ρ†Ρ…ΡƒΠ½ΠΊ}
Π¦ΠΎΠ½Ρ‚Π΅Π½Ρ‚-Π’ΠΈΠΏΠ΅: Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°/ΠΎΠΊΡ‚Π΅Ρ‚-Ρ‚ΠΎΠΊ
{Π›Π°ΠΈΠ΅Ρ€ Π¦Ρ…ΡƒΠ½ΠΊ Π‘ΠΈΠ½Π°Ρ€ΠΈ Π”Π°Ρ‚Π°}".

Π£ супротном, Π½Π΅Ρ›Π΅Ρ‚Π΅ ΠΌΠΎΡ›ΠΈ Π΄Π° сС ΠΏΠΎΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π΄Π°Ρ™Π΅ ΠΎΠ΄ ΠΏΡ€Π²Π΅ Ρ‚Π°Ρ‡ΠΊΠ΅, Ρ˜Π΅Ρ€... УмСсто ΠΎΡ‡Π΅ΠΊΠΈΠ²Π°Π½ΠΎΠ³ ΠΊΠΎΠ΄Π° ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€Π° 202, Π΄ΠΎΠ±ΠΈΡ›Π΅Ρ‚Π΅ 4ΠΊΠΊ.

Π‘Π°Π΄Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚Π°ΠΌ ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΎΠ²Π°ΠΊΠΎ:

  • Π˜Π½ΠΈΡ†ΠΈΡ˜Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡ˜Π°
  • ΠŸΠ°Ρ‚Ρ†Ρ… Ρ€Π°ΠΈΠ»
  • Π£Ρ‡ΠΈΡ‚Π°Π²Π°ΡšΠ΅ Ρ€ΡƒΠΊΠΎΡ…Π²Π°Ρ‚Π°
  • Π£Ρ‡ΠΈΡ‚Π°Π²Π°ΡšΠ΅ манифСста
    Π’Π°Ρ‡ΠΊΠ΅ 2 ΠΈ 3, рСспСктивно, Π±ΠΈΡ›Π΅ ΠΏΠΎΠ½ΠΎΠ²Ρ™Π΅Π½Π΅ ΠΎΠ½ΠΎΠ»ΠΈΠΊΠΎ ΠΏΡƒΡ‚Π° ΠΊΠΎΠ»ΠΈΠΊΠΎ јС ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ ΡƒΡ‡ΠΈΡ‚Π°Ρ‚ΠΈ Ρ€Π΅Π΄ΠΎΠ²Π΅.

ΠŸΡ€Π²ΠΎ, ΠΏΠΎΡ‚Ρ€Π΅Π±Π½Π° Π½Π°ΠΌ јС Π±ΠΈΠ»ΠΎ ΠΊΠ°ΠΊΠ²Π° слика. ΠšΠΎΡ€ΠΈΡΡ‚ΠΈΡ›Ρƒ Π°Ρ€Ρ†Ρ…Π»ΠΈΠ½ΡƒΠΊ:латСст

docker pull archlinux

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Π‘Π°Π΄Π° Ρ›Π΅ΠΌΠΎ Π³Π° сачувати Π»ΠΎΠΊΠ°Π»Π½ΠΎ Π·Π° Π΄Π°Ρ™Ρƒ Π°Π½Π°Π»ΠΈΠ·Ρƒ

docker save c24fe13d37b9 -o savedArch

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Π Π°ΡΠΏΠ°ΠΊΡƒΡ˜Ρ‚Π΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚ΡƒΡ˜ΡƒΡ›Ρƒ Π°Ρ€Ρ…ΠΈΠ²Ρƒ Ρƒ Ρ‚Ρ€Π΅Π½ΡƒΡ‚Π½ΠΈ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡ˜ΡƒΠΌ

tar xvf savedArch

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

Као ΡˆΡ‚ΠΎ Π²ΠΈΠ΄ΠΈΡ‚Π΅, свака линија ΠΆΠΈΠ²ΠΎΡ‚Π° Π½Π°Π»Π°Π·ΠΈ сС Ρƒ посСбном Ρ„ΠΎΠ»Π΄Π΅Ρ€Ρƒ. ПоглСдајмо сада структуру манифСста који смо Π΄ΠΎΠ±ΠΈΠ»ΠΈ

cat manifest.json | json_pp

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

НС ΠΌΠ½ΠΎΠ³ΠΎ. Π”Π° Π²ΠΈΠ΄ΠΈΠΌΠΎ ΡˆΡ‚Π° јС манифСст ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ Π·Π° ΡƒΡ‡ΠΈΡ‚Π°Π²Π°ΡšΠ΅, ΠΏΡ€Π΅ΠΌΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°.

Π˜ΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΏΡƒΠ»Π» ΠΈ Π΄ΠΎΡ†ΠΊΠ΅Ρ€ пусх ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π±Π΅Π· Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° користСћи Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π΅

ΠžΡ‡ΠΈΠ³Π»Π΅Π΄Π½ΠΎ, ΠΏΠΎΡΡ‚ΠΎΡ˜Π΅Ρ›ΠΈ манифСст Π½Π°ΠΌ Π½Π΅ ΠΎΠ΄Π³ΠΎΠ²Π°Ρ€Π°, ΠΏΠ° Ρ›Π΅ΠΌΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΠΈ свој са Π±Π»Π°Ρ†ΠΊΡ˜Π°Ρ†ΠΊΠΎΠΌ ΠΈ ΠΊΡƒΡ€Ρ‚ΠΈΠ·Π°Π½Π°ΠΌΠ°, спасилачким ΡƒΠΆΠ΅Ρ‚ΠΎΠΌ ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ˜Π°ΠΌΠ°.

Π£Π²Π΅ΠΊ Ρ›Π΅ΠΌΠΎ ΠΈΠΌΠ°Ρ‚ΠΈ најмањС Ρ˜Π΅Π΄Π½Ρƒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Ρƒ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΡƒ ΠΈ Π½ΠΈΠ· линија спасавања. Π¨Π΅ΠΌΠ° Π²Π΅Ρ€Π·ΠΈΡ˜Π° 2 (Π°ΠΊΡ‚ΡƒΠ΅Π»Π½Π° Ρƒ Π²Ρ€Π΅ΠΌΠ΅ писања), ΠΌΠ΅Π΄ΠΈΠ°Π’ΠΈΠΏΠ΅ Ρ›Π΅ остати Π½Π΅ΠΏΡ€ΠΎΠΌΠ΅ΡšΠ΅Π½:

echo β€˜{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": config_size,
      "digest": "config_hash"
   },
   "layers": [
      ’ > manifest.json

Након ΠΊΡ€Π΅ΠΈΡ€Π°ΡšΠ° основног манифСста, ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ јС Π΄Π° Π³Π° ΠΏΠΎΠΏΡƒΠ½ΠΈΡ‚Π΅ Π²Π°ΠΆΠ΅Ρ›ΠΈΠΌ ΠΏΠΎΠ΄Π°Ρ†ΠΈΠΌΠ°. Π”Π° бисмо Ρ‚ΠΎ ΡƒΡ€Π°Π΄ΠΈΠ»ΠΈ, користимо јсон шаблон ΠΆΠ΅Π»Π΅Π·Π½ΠΈΡ‡ΠΊΠΎΠ³ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚Π°:

{
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": ${layersSizes[$i]},
         "digest": "sha256:${layersNames[$i]}"
      },

Π”ΠΎΠ΄Π°Ρ›Π΅ΠΌΠΎ Π³Π° Ρƒ манифСст Π·Π° сваку ΡˆΠΈΠ½Ρƒ.

Π—Π°Ρ‚ΠΈΠΌ ΠΌΠΎΡ€Π°ΠΌΠΎ Π΄Π° сазнамо Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π΅ Π΄Π°Ρ‚ΠΎΡ‚Π΅ΠΊΠ΅ ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΠΌΠΎ стубовС Ρƒ манифСсту стварним ΠΏΠΎΠ΄Π°Ρ†ΠΈΠΌΠ°

sed -i "s/config_size/$configSize/g; s/config_hash/$configName/g" $manifestFile

Π‘Π°Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΠΎΠΊΡ€Π΅Π½Π΅Ρ‚Π΅ процСс ΠΏΡ€Π΅ΡƒΠ·ΠΈΠΌΠ°ΡšΠ° ΠΈ сачуватС сСби ΡƒΡƒΠΈΠ΄, који Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΏΡ€Π°Ρ‚ΠΈ свС Π½Π°Ρ€Π΅Π΄Π½Π΅ Π·Π°Ρ…Ρ‚Π΅Π²Π΅.

ΠšΠΎΠΌΠΏΠ»Π΅Ρ‚Π½Π° скрипта ΠΈΠ·Π³Π»Π΅Π΄Π° ΠΎΡ‚ΠΏΡ€ΠΈΠ»ΠΈΠΊΠ΅ ΠΎΠ²Π°ΠΊΠΎ:

#!/bin/bash -eux

imageDir=$1
# url as http://localhost:8081/link/to/docker/registry
url=$2
repoName=$3
tag=$4
manifestFile=$(readlink -f ${imageDir}/manifestCopy)
configFile=$(readlink -f $(find $imageDir -name "*.json" ! -name "manifest.json"))

# calc layers sha 256 sum, rename them accordingly, and add info about each to manifest file
function prepareLayersForUpload() {
  info_file=$imageDir/info
  # lets calculate layers sha256 and use it as layers names further
  layersNames=($(find $imageDir -name "layer.tar" -exec shasum -a 256 {} ; | cut -d" " -f1))

  # rename layers according to shasums. !!!Set required amount of fields for cut command!!!
  # this part definitely can be done easier but i didn't found another way, sry
  find $imageDir -name "layer.tar" -exec bash -c 'mv {} "$(echo {} | cut -d"/" -f1,2)/$(shasum -a 256 {} | cut -d" " -f1)"' ;

  layersSizes=($(find $imageDir -name "*.tar" -exec ls -l {} ; | awk '{print $5}'))

  for i in "${!layersNames[@]}"; do
    echo "{
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": ${layersSizes[$i]},
         "digest": "sha256:${layersNames[$i]}"
      }," >> $manifestFile
  done
  # remove last ','
  truncate -s-2 $manifestFile
  # add closing brakets to keep json consistent
  printf "nt]n}" >> $manifestFile
}

# calc config sha 256 sum and add info about it to manifest
function setConfigProps() {
  configSize=$(ls -l $configFile | awk '{print $5}')
  configName=$(basename $configFile | cut -d"." -f1)

  sed -i "s/config_size/$configSize/g; s/config_hash/$configName/g" $manifestFile
}

#prepare manifest file
prepareLayersForUpload
setConfigProps
cat $manifestFile

# initiate upload and get uuid
uuid=$(curl -s -X POST -I "$url/v2/$repoName/blobs/uploads/" | grep -oP "(?<=Docker-Upload-Uuid: ).+")

# patch layers
# in data-binary we're getting absolute path to layer file
for l in "${!layersNames[@]}"; do
  pathToLayer=$(find $imageDir -name ${layersNames[$l]} -exec readlink -f {} ;)
    curl -v -X PATCH "$url/v2/$repoName/blobs/uploads/$uuid" 
  -H "Content-Length: ${layersSizes[$i]}" 
  -H "Content-Type: application/octet-stream" 
  --data-binary "@$pathToLayer"

# put layer
  curl -v -X PUT "$url/v2/$repoName/blobs/uploads/$uuid?digest=sha256:${layersNames[$i]}" 
  -H 'Content-Type: application/octet-stream' 
  -H "Content-Length: ${layersSizes[$i]}" 
  --data-binary "@$pathToLayer"
done

# patch and put config after all layers
curl -v -X PATCH "$url/v2/$repoName/blobs/uploads/$uuid" 
  -H "Content-Length: $configSize" 
  -H "Content-Type: application/octet-stream" 
  --data-binary "@$configFile"

  curl -v -X PUT "$url/v2/$repoName/blobs/uploads/$uuid?digest=sha256:$configName" 
  -H 'Content-Type: application/octet-stream' 
  -H "Content-Length: $configSize" 
  --data-binary "@$configFile"

# put manifest
curl -v -X PUT "$url/v2/$repoName/manifests/$tag" 
  -H 'Content-Type: application/vnd.docker.distribution.manifest.v2+json' 
  --data-binary "@$manifestFile"

exit 0

ΠΌΠΎΠΆΠ΅ΠΌΠΎ користити Π³ΠΎΡ‚ΠΎΠ²Ρƒ скрипту:

./uploadImage.sh "~/path/to/saved/image" "http://localhost:8081/link/to/docker/registry" myRepoName 1.0

Π£ΠŸΠ”:
Π¨Ρ‚Π° смо Π΄ΠΎΠ±ΠΈΠ»ΠΈ ΠΊΠ°ΠΎ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚?
ΠŸΡ€Π²ΠΎ, ΠΏΡ€Π°Π²ΠΈ ΠΏΠΎΠ΄Π°Ρ†ΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ·Ρƒ, ΠΏΠΎΡˆΡ‚ΠΎ сС тСстови Ρ€Π°Π΄Π΅ Ρƒ Π±Π»Π°Π·Π΅ΠΌΠ΅Ρ‚Π΅Ρ€Ρƒ ΠΈ ΠΏΠΎΠ΄Π°Ρ†ΠΈ ΠΎ Π·Π°Ρ…Ρ‚Π΅Π²ΠΈΠΌΠ° Π΄ΠΎΡ†ΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΡ˜Π΅Π½Ρ‚Π° нису баш ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΠ²Π½ΠΈ, Π·Π° Ρ€Π°Π·Π»ΠΈΠΊΡƒ ΠΎΠ΄ чистог Π₯ВВП Π·Π°Ρ…Ρ‚Π΅Π²Π°.

Π”Ρ€ΡƒΠ³ΠΎ, Ρ‚Ρ€Π°Π½Π·ΠΈΡ†ΠΈΡ˜Π° Π½Π°ΠΌ јС ΠΎΠΌΠΎΠ³ΡƒΡ›ΠΈΠ»Π° Π΄Π° ΠΏΠΎΠ²Π΅Ρ›Π°ΠΌΠΎ Π±Ρ€ΠΎΡ˜ Π²ΠΈΡ€Ρ‚ΡƒΠ΅Π»Π½ΠΈΡ… корисника Π·Π° ΠΎΡ‚ΠΏΡ€Π΅ΠΌΠ°ΡšΠ΅ Π΄ΠΎΡ†ΠΊΠ΅Ρ€-Π° Π·Π° ΠΎΠΊΠΎ 150% ΠΈ Π΄Π° добијСмо просСчно Π²Ρ€Π΅ΠΌΠ΅ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€Π° 20-25% Π±Ρ€ΠΆΠ΅. Π—Π° ΠΏΡ€Π΅ΡƒΠ·ΠΈΠΌΠ°ΡšΠ΅ Π΄ΠΎΡ†ΠΊΠ΅Ρ€-Π°, успСли смо Π΄Π° ΠΏΠΎΠ²Π΅Ρ›Π°ΠΌΠΎ Π±Ρ€ΠΎΡ˜ корисника Π·Π° 500%, Π΄ΠΎΠΊ јС просСчно Π²Ρ€Π΅ΠΌΠ΅ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€Π° смањСно Π·Π° ΠΎΠΊΠΎ 60%.

Π₯Π²Π°Π»Π° Π²Π°ΠΌ Π½Π° паТњи.

Π˜Π·Π²ΠΎΡ€: Π²Π²Π².Ρ…Π°Π±Ρ€.Ρ†ΠΎΠΌ

Π”ΠΎΠ΄Π°Ρ˜ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€