ΠΠΌΠ°Π»ΠΈ ΡΠΌΠΎ 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%.
Π₯Π²Π°Π»Π° Π²Π°ΠΌ Π½Π° ΠΏΠ°ΠΆΡΠΈ.
ΠΠ·Π²ΠΎΡ: Π²Π²Π².Ρ Π°Π±Ρ.ΡΠΎΠΌ