Π£ Π½Π°Ρ Π±ΡΠ»ΠΎ 2 ΠΌΠ΅ΡΠΊΠ° ΡΡΠ°Π²Ρ, 75 ΡΠ°Π±Π»Π΅ΡΠΎΠΊ ΠΌΠ΅ΡΠΊΠ°Π»ΠΈΠ½Π° unix environment, docker ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΠΈ Π·Π°Π΄Π°ΡΠ° ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ docker pull ΠΈ docker push Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
UPD:
ΠΠΎΠΏΡΠΎΡ: ΠΠ»Ρ ΡΠ΅Π³ΠΎ Π²ΡΡ ΡΡΠΎ?
ΠΡΠ²Π΅Ρ: ΠΠ°Π³ΡΡΠ·ΠΎΡΠ½ΠΎΠ΅ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠ΄ΡΠΊΡΠ° (ΠΠ ΡΡΠ΅Π΄ΡΡΠ²Π°ΠΌΠΈ Π±Π°ΡΠ°, ΡΠΊΡΠΈΠΏΡΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Ρ Π² ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΡΡ
ΡΠ΅Π»ΡΡ
). ΠΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄ΠΎΠΊΠ΅Ρ ΠΊΠ»ΠΈΠ΅Π½Ρ Π±ΡΠ»ΠΎ ΡΠ΅ΡΠ΅Π½ΠΎ Π΄Π»Ρ ΡΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ
ΠΏΡΠΎΡΠ»ΠΎΠ΅ΠΊ (Π² ΡΠ°Π·ΡΠΌΠ½ΡΡ
ΠΏΡΠ΅Π΄Π΅Π»Π°Ρ
) ΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ ΡΠΌΡΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π±ΠΎΠ»Π΅Π΅ Π²ΡΡΠΎΠΊΠΎΠΉ Π½Π°Π³ΡΡΠ·ΠΊΠΈ. Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΡΠ±ΡΠ°Π»ΠΈ Π²ΡΠ΅ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ Π΄ΠΎΠΊΠ΅Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°. ΠΠΎΠ»ΡΡΠΈΠ»ΠΈ ΡΡΠ°Π²Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΈΡΡΡΡ Π½Π°Π³ΡΡΠ·ΠΊΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π½Π° ΠΏΡΠΎΠ΄ΡΠΊΡ.
Π ΡΡΠ°ΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈΡΡ ΡΡΠ»Ρ GNU Π²Π΅ΡΡΠΈΠΉ.
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌΡΡ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ ΡΡΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρ.
ΠΡΠ°ΠΊ Π΄Π»Ρ ΡΠ΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ docker pull? Π‘ΠΎΠ³Π»Π°ΡΠ½ΠΎ
"Pull an image or a repository from a registry".
Π’Π°ΠΌ ΠΆΠ΅ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌ ΡΡΡΠ»ΠΊΡ Π½Π°
ΠΡΡΡΠ΄Π° ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ½ΡΡΡ ΡΡΠΎ docker image ΡΡΠΎ Π½Π°Π±ΠΎΡ Π½Π΅ΠΊΠΈΡ
layers, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π² ΡΠ΅Π±Π΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡ
ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΡ
Π² ΠΈΠΌΠ΅Π΄ΠΆΠ΅, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ Π½Π°ΠΌ ΠΈ Π½ΡΠΆΠ½Ρ. ΠΠ°Π»ΡΡΠ΅ ΡΠΌΠΎΡΡΠΈΠΌ Π²
ΠΠ΄Π΅ΡΡ Π³ΠΎΠ²ΠΎΡΠΈΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
"An βimageβ is a combination of a JSON manifest and individual layer files. The process of pulling an > image centers around retrieving these two components."
ΠΡΠ°ΠΊ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ°Π³ ΡΠΎΠ³Π»Π°ΡΠ½ΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΡΡΠΎ βPulling an Image Manifestβ.
ΠΡΠ»ΠΈΡΡ ΠΌΡ Π΅Π³ΠΎ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ, Π½ΠΎ Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ· Π½Π΅Π³ΠΎ Π½Π°ΠΌ Π½ΡΠΆΠ½Ρ. ΠΠ°Π»ΡΡΠ΅ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π°ΠΏΡΠΎΡΠ°: GET /v2/{name}/manifests/{reference}
"The name and reference parameter identify the image and are required. The reference may include a tag or digest."
ΠΠ°Ρ Π΄ΠΎΠΊΠ΅Ρ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΡΠ°Π·Π²Π΅ΡΠ½ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ, ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ Π·Π°ΠΏΡΠΎΡ:
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}"
βAccess to a layer will be gated by the name of the repository but is identified uniquely in the registry by digest.β
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 Π°ΡΡ ΠΈΠ²Ρ, ΡΠ°ΡΠΏΠ°ΠΊΠΎΠ²Π°Π² ΠΊΠΎΡΠΎΡΡΠ΅ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΈΠΌΠ΅Π΄ΠΆΠ°.
ΠΠ°ΠΏΠΈΡΠ΅ΠΌ Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠΉ Π±Π°Ρ ΡΠΊΡΠΈΠΏΡ ΡΡΠΎΠ±Ρ Π²ΡΡ ΡΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ
#!/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Ρ Ρ .
Π’Π΅ΠΏΠ΅ΡΡ Π°Π»Π³ΠΎΡΠΈΡΠΌ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΊΠ°ΠΊ:
- ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ
- ΠΠ°ΡΡ Π»Π΅Π΅ΡΠ°
- ΠΠ°Π³ΡΡΠ·ΠΊΠ° Π»Π΅Π΅ΡΠ°
- ΠΠ°Π³ΡΡΠ·ΠΊΠ° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°
ΠΡΠ½ΠΊΡΡ 2 ΠΈ 3 ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ Π±ΡΠ΄ΡΡ ΠΏΠΎΠ²ΡΠΎΡΡΡΡΡΡ ΡΡΠΎΠ»ΡΠΊΠΎ ΡΠ°Π·, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π»Π΅Π΅ΡΠΎΠ² Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ.
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° Π½Π°ΠΌ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡΡ Π»ΡΠ±ΠΎΠΉ ΠΈΠΌΠ΅Π΄ΠΆ. Π― Π±ΡΠ΄Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ archlinux:latest
docker pull archlinux
Π’Π΅ΠΏΠ΅ΡΡ ΡΠΎΡ ΡΠ°Π½ΠΈΠΌ Π΅Π³ΠΎ ΡΠ΅Π±Π΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ ΡΠ°Π·Π±ΠΎΡΠ°
docker save c24fe13d37b9 -o savedArch
Π Π°ΡΠΏΠ°ΠΊΡΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠΉ Π°ΡΡ ΠΈΠ² Π² ΡΠ΅ΠΊΡΡΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ
tar xvf savedArch
ΠΠ°ΠΊ Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΆΠ΄ΡΠΉ Π»Π΅Π΅Ρ Π»Π΅ΠΆΠΈΡ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΉ ΠΏΠ°ΠΏΠΊΠ΅. Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ Π½Π° ΡΡΡΡΡΠΊΡΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ
cat manifest.json | json_pp
ΠΠ΅ Π³ΡΡΡΠΎ. ΠΠΎΡΠΌΠΎΡΡΠΈΠΌ ΠΊΠ°ΠΊΠΎΠΉ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π½ΡΠΆΠ΅Π½ Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ, ΡΠΎΠ³Π»Π°ΡΠ½ΠΎ
ΠΡΠ΅Π²ΠΈΠ΄Π½ΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠΉ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π½Π°ΠΌ Π½Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ, Π·Π½Π°ΡΠΈΡ ΡΠ΄Π΅Π»Π°Π΅ΠΌ ΡΠ²ΠΎΠΉ Ρ Π±Π»ΡΠΊΠ΄ΠΆΠ΅ΠΊΠΎΠΌ ΠΈ ΠΊΡΡΡΠΈΠ·Π°Π½ΠΊΠ°ΠΌΠΈ Π»Π΅Π΅ΡΠ°ΠΌΠΈ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³Π°ΠΌΠΈ.
Π£ Π½Π°Ρ Π²ΡΠ΅Π³Π΄Π° Π±ΡΠ΄Π΅Ρ ΠΌΠΈΠ½ΠΌΡΠΌ ΠΎΠ΄ΠΈΠ½ config ΡΠ°ΠΉΠ» ΠΈ ΠΌΠ°ΡΡΠΈΠ² Π»Π΅Π΅ΡΠΎΠ². ΠΠ΅ΡΡΠΈΡ ΡΡ Π΅ΠΌΡ 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.0
UPD:
Π§ΡΠΎ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ Π² ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅?
ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ
, ΡΠ΅Π°Π»ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΠΎΡ ΡΠ΅ΡΡΡ Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ Π² blazemeter ΠΈ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎ Π·Π°ΠΏΡΠΎΡΠ°ΠΌ Π΄ΠΎΠΊΠ΅Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π²Π΅ΡΡΠΌΠ° Π½Π΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ²Π½ΡΠ΅ Π² ΠΎΡΠ»ΠΈΡΠΈΠΈ ΠΎΡ ΡΠΈΡΡΡΡ
HTTP Π·Π°ΠΏΡΠΎΡΠΎΠ².
ΠΠΎ-Π²ΡΠΎΡΡΡ , ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠ» Π½Π°ΠΌ ΡΠ²Π΅Π»ΠΈΡΠΈΡΡ ΠΊΠΎΠ»Π»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ Π΄Π»Ρ docker upload ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ Π½Π° 150% ΠΈ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΏΡΠΈ ΡΡΠΎΠΌ avg response time Π½Π° 20-25% Π±ΡΡΡΡΠ΅Π΅. ΠΠ»Ρ docker download ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ ΡΠ²Π΅Π»ΠΈΡΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ Π½Π° 500%, avg response time ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΠ½ΠΈΠ·ΠΈΠ»ΡΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ Π½Π° 60%.
Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com