ΠΠΌΠ°Ρ ΠΌΠ΅ 2 ΡΠΎΡΠ±ΠΈ ΡΡΠ΅Π²Π°, 75 ΡΠ°Π±Π»Π΅ΡΠΊΠΈ ΠΌΠ΅ΡΠΊΠ°Π»ΠΈΠ½, ΡΡΠ΅Π΄Π° Π½Π° Unix, Docker Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ ΠΈ Π·Π°Π΄Π°ΡΠ° Π΄Π° ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡΠ΅ docker pull ΠΈ docker push Π±Π΅Π· Docker ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.

UPD:
ΠΡΠΏΡΠΎΡ: ΠΠ° ΠΊΠ°ΠΊΠ²ΠΎ Π΅ Π²ΡΠΈΡΠΊΠΎ ΡΠΎΠ²Π°?
ΠΡΠ³ΠΎΠ²ΠΎΡ: ΠΠ°Π³ΡΡΠ·ΠΎΡΠ½ΠΎ ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ΄ΡΠΊΡΠ° (ΠΠ ΡΡΠ΅Π· bash, ΡΠΊΡΠΈΠΏΡΠΎΠ²Π΅ΡΠ΅ ΡΠ° ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π΅Π½ΠΈ Π·Π° ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΈ ΡΠ΅Π»ΠΈ). Π Π΅ΡΠ΅Π½ΠΎ Π΅ Π΄Π° Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Docker ΠΊΠ»ΠΈΠ΅Π½Ρ, Π·Π° Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ°Π»ΡΡ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈΡΠ΅ ΡΠ»ΠΎΠ΅Π²Π΅ (Π² ΡΠ°Π·ΡΠΌΠ½ΠΈ Π³ΡΠ°Π½ΠΈΡΠΈ) ΠΈ ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΎ Π΄Π° ΡΠ΅ Π΅ΠΌΠΈΡΠΈΡΠ° ΠΏΠΎ-Π²ΠΈΡΠΎΠΊΠ° Π½Π°ΡΠΎΠ²Π°ΡΠ΅Π½ΠΎΡΡ. Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° Π±ΡΡ
Π° ΠΏΡΠ΅ΠΌΠ°Ρ
Π½Π°ΡΠΈ Π²ΡΠΈΡΠΊΠΈ ΡΠΈΡΡΠ΅ΠΌΠ½ΠΈ Π·Π°Π±Π°Π²ΡΠ½ΠΈΡ Π½Π° Docker ΠΊΠ»ΠΈΠ΅Π½ΡΠ°. ΠΠΎΠ»ΡΡΠΈΡ
ΠΌΠ΅ ΡΡΠ°Π²Π½ΠΈΡΠ΅Π»Π½ΠΎ ΡΠΈΡΡΠ° Π½Π°ΡΠΎΠ²Π°ΡΠ΅Π½ΠΎΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ Π½Π° ΠΏΡΠΎΠ΄ΡΠΊΡΠ°.
Π ΡΡΠ°ΡΠΈΡΡΠ° ΡΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ ΠΎΡ Π²Π΅ΡΡΠΈΡΡΠ° Π½Π° GNU.
ΠΡΡΠ²ΠΎ Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ ΠΏΡΠ°Π²ΡΡ ΡΠ΅Π·ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ.
Π ΡΠ°ΠΊΠ°, Π·Π° ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° docker pull? Π‘ΠΏΠΎΡΠ΅Π΄ :
"ΠΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ ΠΎΡ ΡΠ΅Π³ΠΈΡΡΡΡ".
Π’Π°ΠΌ Π½Π°ΠΌΠΈΡΠ°ΠΌΠ΅ ΠΈ Π²ΡΡΠ·ΠΊΠ° ΠΊΡΠΌ .

ΠΡΡΡΠΊ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌ, ΡΠ΅ Docker ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π΅ Π½Π°Π±ΠΎΡ ΠΎΡ ΡΠ»ΠΎΠ΅Π²Π΅, ΠΊΠΎΠΈΡΠΎ ΡΡΠ΄ΡΡΠΆΠ°Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ, ΠΊΠΎΠΈΡΠΎ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ ΡΠ° Π½ΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ. Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ°Π·Π³Π»Π΅ΠΆΠ΄Π°ΠΌΠ΅ .
Π’ΡΠΊ ΡΠ΅ ΠΊΠ°Π·Π²Π° ΡΠ»Π΅Π΄Π½ΠΎΡΠΎ:
"ΠΠ΄Π½ΠΎ 'ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅' Π΅ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΡ ΠΎΡ JSON ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ ΠΈ ΠΈΠ½Π΄ΠΈΠ²ΠΈΠ΄ΡΠ°Π»Π½ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ Π½Π° ΡΠ»ΠΎΠ΅Π²Π΅. ΠΡΠΎΡΠ΅ΡΡΡ Π½Π° ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π½Π° Π΅Π΄Π½ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ ΡΡΡΡΠ΅Π΄ΠΎΡΠΎΡΠ°Π²Π° Π²ΡΡΡ Ρ ΠΈΠ·Π²Π»ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΠ΅Π·ΠΈ Π΄Π²Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°."
Π ΡΠ°ΠΊΠ°, ΠΏΡΡΠ²Π°ΡΠ° ΡΡΡΠΏΠΊΠ° ΡΠΏΠΎΡΠ΅Π΄ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡΠ° Π΅ βΠΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ.β.
ΠΡΠΌΠ° Π΄Π° Π³ΠΎ ΠΈΠ·ΡΠ΅Π³Π»ΡΠΌΠ΅, Π½ΠΎ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡΡΠ° ΠΎΡ Π½Π΅Π³ΠΎ Π½ΠΈ Π΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠ°. Π‘Π»Π΅Π΄Π²Π° ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° Π·Π°ΡΠ²ΠΊΠ°: GET /v2/{name}/manifests/{reference}
"ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΡΠ΅ name ΠΈ reference ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΈ ΡΠ° Π·Π°Π΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΈ. ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡΡΡ reference ΠΌΠΎΠΆΠ΅ Π΄Π° Π²ΠΊΠ»ΡΡΠ²Π° ΠΌΠ°ΡΠΊΠ΅Ρ ΠΈΠ»ΠΈ Ρ Π΅Ρ."
ΠΠ°ΡΠ΅ΡΠΎ Docker Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π΅ ΡΠ°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΎ Π»ΠΎΠΊΠ°Π»Π½ΠΎ, Π΄Π° ΠΎΠΏΠΈΡΠ°ΠΌΠ΅ Π΄Π° ΠΈΠ·ΠΏΡΠ»Π½ΠΈΠΌ Π·Π°ΡΠ²ΠΊΠ°ΡΠ°:
curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/manifests/1.1.1" -H "header_if_needed"
Π ΠΎΡΠ³ΠΎΠ²ΠΎΡ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ JSON, ΠΎΡ ΠΊΠΎΠΉΡΠΎ Π½ΠΈ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π°Ρ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΡΠ°ΠΌΠΎ ΡΠ»ΠΎΠ΅Π²Π΅ΡΠ΅, ΠΏΠΎ-ΡΠΎΡΠ½ΠΎ ΡΠ΅Ρ Π½ΠΈΡΠ΅ Ρ Π΅ΡΠΎΠ²Π΅. ΠΠΎΠ»ΡΡΠ°Π²Π°ΠΉΠΊΠΈ Π³ΠΈ, ΠΌΠΎΠΆΠ΅ΠΌ Π·Π° Π²ΡΠ΅ΠΊΠΈ Π΅Π΄ΠΈΠ½ Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ ΡΠ»Π΅Π΄Π²Π°ΡΠ°ΡΠ° Π·Π°ΡΠ²ΠΊΠ°: "GET /v2/{name}/blobs/{digest}".
βΠΠΎΡΡΡΠΏΡΡ Π΄ΠΎ Π΅Π΄ΠΈΠ½ ΡΠ»ΠΎΠΉ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ ΠΎΡ ΠΈΠΌΠ΅ΡΠΎ Π½Π° Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ, Π½ΠΎ ΡΠ½ΠΈΠΊΠ°Π»Π½ΠΎ ΡΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠ° Π² ΡΠ΅Π³ΠΈΡΡΡΡΠ° ΠΏΠΎ Ρ Π΅Ρ.β
Π₯Π΅ΡΡΡ Π² ΡΠ»ΡΡΠ°Ρ Π΅ Ρ Π΅ΡΡΡ, ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅.
ΠΠΏΠΈΡΠ²Π°ΠΌΠ΅
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
Ρ.Π΅. ΡΠ»ΠΎΠ΅Π²Π΅ΡΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ²Π°Ρ tar Π°ΡΡ ΠΈΠ²ΠΈ, ΠΊΠΎΠΈΡΠΎ, Π°ΠΊΠΎ Π±ΡΠ΄Π°Ρ ΡΠ°Π·Π°ΡΡ ΠΈΠ²ΠΈΡΠ°Π½ΠΈ Π² ΡΡΠΎΡΠ²Π΅ΡΠ½Π°ΡΠ° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡ, ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅ΡΠΎ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ.
Π©Π΅ Π½Π°ΠΏΠΈΡΠ΅ΠΌ ΠΌΠ°Π»ΡΠΊ bash ΡΠΊΡΠΈΠΏΡ, Π·Π° Π΄Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ Π²ΡΠΈΡΠΊΠΎ ΡΠΎΠ²Π°.
#!/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 β docker push
Π’ΡΠΊ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-ΡΠ»ΠΎΠΆΠ½ΠΎ.
ΠΠ΅ΠΊΠ° Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌ ΠΎΡΠ½ΠΎΠ²ΠΎ Ρ . Π ΡΠ°ΠΊΠ°, ΡΡΡΠ±Π²Π° Π΄Π° ΠΊΠ°ΡΠΈΠΌ Π²ΡΠ΅ΠΊΠΈ ΡΠ»ΠΎΠΉ, Π΄Π° ΡΡΠ±Π΅ΡΠ΅ΠΌ ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ ΠΈ Π΄Π° Π³ΠΎ ΠΊΠ°ΡΠΈΠΌ ΡΡΡΠΎ. ΠΠ²ΡΡΠΈ ΠΏΡΠΎΡΡΠΎ.
Π‘Π»Π΅Π΄Π²Π°ΠΉΠΊΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡΠ°, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΡΠ°Π·Π΄Π΅Π»ΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΠ° Π½Π° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΡΡΠΏΠΊΠΈ:
- ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠ° β "POST \/v2\/{repoName}\/blobs\/uploads\/"
- ΠΠ°ΡΠ²Π°Π½Π΅ Π½Π° ΡΠ»ΠΎΠΉ (ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡΠ½ΠΎ ΠΊΠ°ΡΠ²Π°Π½Π΅, Ρ.Π΅. Π²ΡΠ΅ΠΊΠΈ ΡΠ»ΠΎΠΉ ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌΠ΅ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ) β "PUT \/v2\/{repoName}\/blobs\/uploads\/{uuid}?digest={digest}
Content-Length: {size of layer}
Content-Type: application\/octet-stream
Layer Binary Data". - ΠΠ°ΡΠ²Π°Π½Π΅ Π½Π° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° β "PUT \/v2\/{repoName}\/manifests\/{reference}".
ΠΠΎ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡΠ° Π΅ ΠΏΡΠΎΠΏΡΡΠ½Π°ΡΠ° Π΅Π΄Π½Π° ΡΡΡΠΏΠΊΠ°, Π±Π΅Π· ΠΊΠΎΡΡΠΎ Π½ΠΈΡΠΎ Π½ΡΠΌΠ° Π΄Π° ΡΡΠ°Π½Π΅. ΠΠ° ΠΌΠΎΠ½ΠΎΠ»ΠΈΡΠ½ΠΎ ΠΊΠ°ΡΠ²Π°Π½Π΅, ΠΊΠ°ΠΊΡΠΎ ΠΈ Π·Π° ΡΠ°ΡΡΠΈΡΠ½ΠΎ (chunked), ΠΏΡΠ΅Π΄ΠΈ Π΄Π° ΠΊΠ°ΡΠΈΠΌ ΡΠ»ΠΎΡ, Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΠΈΠ·ΠΏΡΠ»Π½ΠΈΠΌ PATCH Π·Π°ΡΠ²ΠΊΠ°:
"PATCH \/v2\/{repoName}\/blobs\/uploads\/{uuid}
Content-Length: {size of chunk}
Content-Type: application\/octet-stream
{Layer Chunk Binary Data}".
Π ΠΏΡΠΎΡΠΈΠ²Π΅Π½ ΡΠ»ΡΡΠ°ΠΉ, Π½ΡΠΌΠ° Π΄Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΡΠ΅ Π·Π° ΡΠ»Π΅Π΄Π²Π°ΡΠ°ΡΠ° ΡΡΡΠΏΠΊΠ°, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π²ΠΌΠ΅ΡΡΠΎ ΠΎΡΠ°ΠΊΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ΄ Π½Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡ 202 ΡΠ΅ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΡΠ΅ 4Ρ Ρ .
Π‘Π΅Π³Π° Π°Π»Π³ΠΎΡΠΈΡΡΠΌΡΡ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΠ°ΠΊΠ°:
- ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ
- Patch Π½Π° ΡΠ»ΠΎΡ
- ΠΠ°ΡΠ²Π°Π½Π΅ Π½Π° ΡΠ»ΠΎΡ
- ΠΠ°ΡΠ²Π°Π½Π΅ Π½Π° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°
Π‘ΡΡΠΏΠΊΠΈ 2 ΠΈ 3 ΡΠ΅ ΡΠ΅ ΠΏΠΎΠ²ΡΠ°ΡΡΡ ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΡΡΠΈ, ΠΊΠΎΠ»ΠΊΠΎΡΠΎ ΡΠ»ΠΎΠ΅Π²Π΅ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΠΊΠ°ΡΠ°Ρ.
ΠΠ° Π½Π°ΡΠ°Π»ΠΎ Π½ΠΈ ΡΡΡΠ±Π²Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅. ΠΠ· ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ archlinux:latest
docker pull archlinux
Π‘Π΅Π³Π° ΡΠ΅ Π³ΠΎ Π·Π°ΠΏΠ°Π·ΠΈΠΌ Π»ΠΎΠΊΠ°Π»Π½ΠΎ Π·Π° ΠΏΠΎ-Π½Π°ΡΠ°ΡΡΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·
docker save c24fe13d37b9 -o savedArch
Π Π°Π·Π°ΡΡ ΠΈΠ²ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π°ΡΡ ΠΈΠ² Π² ΡΠ΅ΠΊΡΡΠ°ΡΠ° Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ
tar xvf savedArch
ΠΠ°ΠΊΡΠΎ Π²ΠΈΠΆΠ΄Π°ΠΌΠ΅, Π²ΡΠ΅ΠΊΠΈ ΡΠ»ΠΎΠΉ Π΅ Π² ΠΎΡΠ΄Π΅Π»Π½Π° ΠΏΠ°ΠΏΠΊΠ°. ΠΠ΅ΠΊΠ° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°, ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅
cat manifest.json | json_pp
ΠΠ΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ. ΠΠ΅ΠΊΠ° Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊΡΠ² ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌ Π·Π° ΠΊΠ°ΡΠ²Π°Π½Π΅, ΡΠΏΠΎΡΠ΅Π΄ .

ΠΡΠ΅Π²ΠΈΠ΄Π½ΠΎ, ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°ΡΠΈΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π½Π΅ Π½ΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠΆΠ΄Π°, Π·Π½Π°ΡΠΈ ΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ Π½Π°Ρ Ρ Π±Π»ΡΡΡΠ°Π½ΠΊΠΈ ΠΈ ΠΊΡΡΡΠΈΠ·Π°Π½ΠΊΠΈ, ΡΠ»ΠΎΠ΅Π²Π΅ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ.
ΠΠΈΠ½Π°Π³ΠΈ ΡΠ΅ ΠΈΠΌΠ°ΠΌΠ΅ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ Π΅Π΄ΠΈΠ½ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΡΠ°ΠΉΠ» ΠΈ ΠΌΠ°ΡΠΈΠ² ΠΎΡ ΡΠ»ΠΎΠ΅Π²Π΅. ΠΠ΅ΡΡΠΈΡΡΠ° Π½Π° ΡΡ Π΅ΠΌΠ°ΡΠ° Π΅ 2 (Π°ΠΊΡΡΠ°Π»Π½Π° ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π½Π°ΠΏΠΈΡΠ²Π°Π½Π΅ Π½Π° ΡΡΠ°ΡΠΈΡΡΠ°), mediaType ΠΎΡΡΠ°Π²ΡΠΌΠ΅ Π±Π΅Π· ΠΏΡΠΎΠΌΡΠ½Π°:
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Π‘Π»Π΅Π΄ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ, Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π³ΠΎ Π·Π°ΠΏΡΠ»Π½ΠΈΠΌ Ρ Π²Π°Π»ΠΈΠ΄Π½ΠΈ Π΄Π°Π½Π½ΠΈ. ΠΠ° ΡΠΎΠ²Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΡΠ°Π±Π»ΠΎΠ½ 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Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ½ΠΈΡΠΈΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠΎΡΠ΅ΡΠ° Π½Π° ΠΊΠ°ΡΠ²Π°Π½Π΅ ΠΈ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΠΌ uuid, ΠΊΠΎΠΉΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΡΡΠΏΡΡΡΡΠ²Π° Π²ΡΠΈΡΠΊΠΈ ΡΠ»Π΅Π΄Π²Π°ΡΠΈ Π·Π°ΡΠ²ΠΊΠΈ.
Π¦Π΅Π»ΠΈΡΡ ΡΠΊΡΠΈΠΏΡ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡ Π½Π°ΡΠΈΠ½:
#!/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.0UPD:
ΠΠ°ΠΊΠ²ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡ
ΠΌΠ΅ Π² ΡΠ΅Π·ΡΠ»ΡΠ°Ρ?
ΠΡΡΠ²ΠΎ, ΡΠ΅Π°Π»Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ·, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠ΅ΡΡΠΎΠ²Π΅ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°Ρ Π² blazemeter ΠΈ Π΄Π°Π½Π½ΠΈΡΠ΅ ΠΎΡ Π·Π°ΡΠ²ΠΊΠΈΡΠ΅ Π½Π° docker ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΡΠ° Π΄ΠΎΡΡΠ° Π½Π΅ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ²Π½ΠΈ Π² ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Ρ ΡΠΈΡΡΠΈΡΠ΅ HTTP Π·Π°ΡΠ²ΠΊΠΈ.
ΠΠ° Π²ΡΠΎΡΠΎ ΠΌΡΡΡΠΎ, ΠΏΡΠ΅ΠΌΠΈΠ½Π°Π²Π°Π½Π΅ΡΠΎ Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° ΡΠ²Π΅Π»ΠΈΡΠΈΠΌ Π±ΡΠΎΡ Π½Π° Π²ΠΈΡΡΡΠ°Π»Π½ΠΈΡΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ Π·Π° docker upload Ρ ΠΏΡΠΈΠ±Π»ΠΈΠ·ΠΈΡΠ΅Π»Π½ΠΎ 150% ΠΈ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ avg response time Ρ 20-25% ΠΏΠΎ-Π±ΡΡΠ·ΠΎ. ΠΠ° docker download ΡΡΠΏΡΡ ΠΌΠ΅ Π΄Π° ΡΠ²Π΅Π»ΠΈΡΠΈΠΌ Π±ΡΠΎΡ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅ Ρ 500%, ΠΊΠ°ΡΠΎ avg response time ΠΏΡΠΈ ΡΠΎΠ²Π° Π½Π°ΠΌΠ°Π»Ρ Ρ ΠΎΠΊΠΎΠ»ΠΎ 60%.
ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ Π²ΠΈ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ΡΠΎ.
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
