ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

Π˜ΠΌΠ°Ρ…ΠΌΠ΅ 2 Ρ‚ΠΎΡ€Π±ΠΈ с Ρ‚Ρ€Π΅Π²Π°, 75 Ρ‚Π°Π±Π»Π΅Ρ‚ΠΊΠΈ мСскалин unix срСда, Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π·Π° Π΄ΠΎΠΊΠ΅Ρ€ΠΈ ΠΈ Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° Π΄Π° Π²Π½Π΅Π΄Ρ€ΠΈΠΌ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ Π·Π° изтСглянС ΠΈ изтСглянС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚.

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

UPS:
Π’ΡŠΠΏΡ€ΠΎΡ: Π—Π° ΠΊΠ°ΠΊΠ²ΠΎ Π΅ всичко Ρ‚ΠΎΠ²Π°?
ΠžΡ‚Π³ΠΎΠ²ΠΎΡ€: Π—Π°Ρ€Π΅Π΄Π΅Ρ‚Π΅ тСстванС Π½Π° ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π° (НЕ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ bash, скриптовСтС са прСдоставСни Π·Π° ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΈ Ρ†Π΅Π»ΠΈ). Π‘Π΅ΡˆΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΎ Π΄Π° Π½Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΡŠΡ‚ Π·Π° намаляванС Π½Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈΡ‚Π΅ слоСвС (Π² Ρ€Π°Π·ΡƒΠΌΠ½ΠΈ Π³Ρ€Π°Π½ΠΈΡ†ΠΈ) ΠΈ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ Π΄Π° сС Π΅ΠΌΡƒΠ»ΠΈΡ€Π° ΠΏΠΎ-високо Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅. Π’ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ²Π° всички систСмни забавяния Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° Docker бяха ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π°Ρ‚ΠΈ. ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ сравнитСлно чист Ρ‚ΠΎΠ²Π°Ρ€ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π²ΡŠΡ€Ρ…Ρƒ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π°.
Бтатията ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° GNU вСрсии Π½Π° инструмСнти.

ΠŸΡŠΡ€Π²ΠΎ, Π½Π΅ΠΊΠ° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΊΠ°ΠΊΠ²ΠΎ правят Ρ‚Π΅Π·ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ.

И Ρ‚Π°ΠΊΠ°, Π·Π° ΠΊΠ°ΠΊΠ²ΠΎ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° docker pull? Π‘ΠΏΠΎΡ€Π΅Π΄ докумСнтация:

β€žΠ˜Π·Ρ‚Π΅Π³Π»Π΅Ρ‚Π΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ ΠΎΡ‚ Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€β€œ.

Π’Π°ΠΌ Π½Π°ΠΌΠΈΡ€Π°ΠΌΠ΅ ΠΈ Π²Ρ€ΡŠΠ·ΠΊΠ° към Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ изобраТСния, ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΈ ΠΈ Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ΠΈ Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅.

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

ΠžΡ‚ Ρ‚ΡƒΠΊ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ, Ρ‡Π΅ Π΄ΠΎΠΊΠ΅Ρ€ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ слоСвС, ΠΊΠΎΠΈΡ‚ΠΎ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‚ информация Π·Π° послСднитС ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ Π΅ Ρ‚ΠΎΠ²Π°, ΠΎΡ‚ ΠΊΠΎΠ΅Ρ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°ΠΌΠ΅ API Π½Π° Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π°.

Π’Π°ΠΌ сС ΠΊΠ°Π·Π²Π° слСдното:

β€žΠ˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΅ комбинация ΠΎΡ‚ JSON манифСст ΠΈ ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅ Π½Π° слоя. ΠŸΡ€ΠΎΡ†Π΅ΡΡŠΡ‚ Π½Π° изтСглянС Π½Π° > ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сС ΡΡŠΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡Π°Π²Π° ΠΎΠΊΠΎΠ»ΠΎ ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚Π΅Π·ΠΈ Π΄Π²Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°.β€œ

Π’Π°ΠΊΠ° Ρ‡Π΅ ΠΏΡŠΡ€Π²Π°Ρ‚Π° ΡΡ‚ΡŠΠΏΠΊΠ° спорСд докумСнтацията Π΅ β€žΠ˜Π·Ρ‚Π΅Π³Π»ΡΠ½Π΅ Π½Π° манифСст Π½Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅".

Π Π°Π·Π±ΠΈΡ€Π° сС, няма Π΄Π° Π³ΠΎ снимамС, Π½ΠΎ ΠΈΠΌΠ°ΠΌΠ΅ Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚ Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΎΡ‚ Π½Π΅Π³ΠΎ. Π‘Π»Π΅Π΄Π½ΠΎΡ‚ΠΎ Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½Π° заявка: 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"

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

Π’ ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ 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

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

Π”Π° Π²ΠΈΠ΄ΠΈΠΌ какъв Ρ„Π°ΠΉΠ» ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ Π½Π°ΠΉ-накрая ΠΊΠ°Ρ‚ΠΎ ΠΏΡŠΡ€Π²Π° спаситСлна линия.

file firstLayer

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

Ρ‚Π΅Π·ΠΈ. lifelines са 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 - Π΄ΠΎΠΊΠ΅Ρ€ натисканС

Π’ΠΎΠ²Π° Ρ‰Π΅ бъдС ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-слоТно.

Π”Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ ΠΎΡ‚Π½ΠΎΠ²ΠΎ с докумСнтация. Π’Π°ΠΊΠ° Ρ‡Π΅ трябва Π΄Π° ΠΈΠ·Ρ‚Π΅Π³Π»ΠΈΠΌ всСки Π»ΠΈΠ΄Π΅Ρ€, Π΄Π° ΡΡŠΠ±Π΅Ρ€Π΅ΠΌ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ манифСст ΠΈ Π΄Π° Π³ΠΎ ΠΈΠ·Ρ‚Π΅Π³Π»ΠΈΠΌ ΡΡŠΡ‰ΠΎ. ИзглСТда просто.

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΡƒΡ‡ΠΈΠΌ докумСнтацията, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ€Π°Π·Π΄Π΅Π»ΠΈΠΌ процСса Π½Π° изтСглянС Π½Π° няколко ΡΡ‚ΡŠΠΏΠΊΠΈ:

  • Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π½Π° процСса - "POST /v2/{repoName}/blobs/uploads/"
  • ΠšΠ°Ρ‡Π²Π°Π½Π΅ Π½Π° спаситСлна линия (Ρ‰Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π½ΠΎ ΠΊΠ°Ρ‡Π²Π°Π½Π΅, Ρ‚.Π΅. ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°ΠΌΠ΅ всяка спаситСлна линия Π² Π½Π΅ΠΉΠ½Π°Ρ‚Π° цялост) - β€žPUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
    Π”ΡŠΠ»ΠΆΠΈΠ½Π° Π½Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ: {Ρ€Π°Π·ΠΌΠ΅Ρ€ Π½Π° слоя}
    Content-Type: ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅/ΠΎΠΊΡ‚Π΅Ρ‚-ΠΏΠΎΡ‚ΠΎΠΊ
    Π‘Π»ΠΎΠΉ Π΄Π²ΠΎΠΈΡ‡Π½ΠΈ Π΄Π°Π½Π½ΠΈ".
  • Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° манифСста - "PUT /v2/{repoName}/manifests/{reference}".

Но докумСнтацията пропуска Π΅Π΄Π½Π° ΡΡ‚ΡŠΠΏΠΊΠ°, Π±Π΅Π· която Π½ΠΈΡ‰ΠΎ няма Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ. Π—Π° ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π½ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π·Π° частично (Π½Π° ΠΏΠ°Ρ€Ρ‡Π΅Ρ‚Π°), ΠΏΡ€Π΅Π΄ΠΈ Π΄Π° Π·Π°Ρ€Π΅Π΄ΠΈΡ‚Π΅ рСлсата, трябва Π΄Π° ΠΈΠ·ΠΏΡŠΠ»Π½ΠΈΡ‚Π΅ PATCH заявка:

"ΠšΠžΠ Π•ΠšΠ¦Π˜Π― /v2/{repoName}/blobs/uploads/{uuid}
Π”ΡŠΠ»ΠΆΠΈΠ½Π° Π½Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ: {size of chunk}
Content-Type: ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅/ΠΎΠΊΡ‚Π΅Ρ‚-ΠΏΠΎΡ‚ΠΎΠΊ
{Layer Chunk Binary Data}".

Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π΅Π½ случай няма Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅Ρ‚Π΅ ΠΎΡ‚Π²ΡŠΠ΄ ΠΏΡŠΡ€Π²Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ°, Π·Π°Ρ‰ΠΎΡ‚ΠΎ... ВмСсто очаквания ΠΊΠΎΠ΄ Π·Π° ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ 202, Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ 4xx.

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

  • Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ
  • РСлса Π·Π° ΠΊΡ€ΡŠΠΏΠΊΠ°
  • Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€Π°ΠΏΠ΅Ρ‚Π°
  • Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° манифСста
    Π’ΠΎΡ‡ΠΊΠΈ 2 ΠΈ 3, ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ, Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΡŠΡ‚ΠΈ, ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ броя Ρ€Π΅Π΄ΠΎΠ²Π΅ трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π·Π°Ρ€Π΅Π΄Π΅Π½ΠΈ.

ΠŸΡŠΡ€Π²ΠΎ, ΠΈΠΌΠ°ΠΌΠ΅ Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚ всяко ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅. Π©Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ archlinux:latest

docker pull archlinux

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° Π³ΠΎ Π·Π°ΠΏΠ°Π·ΠΈΠΌ Π»ΠΎΠΊΠ°Π»Π½ΠΎ Π·Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π΅Π½ Π°Π½Π°Π»ΠΈΠ·

docker save c24fe13d37b9 -o savedArch

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

Π Π°Π·ΠΎΠΏΠ°ΠΊΠΎΠ²Π°ΠΉΡ‚Π΅ получСния Π°Ρ€Ρ…ΠΈΠ² Π² Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° дирСктория

tar xvf savedArch

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

ΠšΠ°ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅, всяка спаситСлна линия Π΅ Π² ΠΎΡ‚Π΄Π΅Π»Π½Π° ΠΏΠ°ΠΏΠΊΠ°. Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ структурата Π½Π° манифСста, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅

cat manifest.json | json_pp

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

НС ΠΌΠ½ΠΎΠ³ΠΎ. НСка Π²ΠΈΠ΄ΠΈΠΌ какъв манифСст Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π·Π° Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅, спорСд докумСнтация.

ВнСдряванС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° изтСглянС ΠΈ натисканС Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π±Π΅Π· Π΄ΠΎΠΊΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰ HTTP заявки

ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ΠΈΡΡ‚ манифСст Π½Π΅ Π½ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠΆΠ΄Π°, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‰Π΅ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ наш собствСн с Π±Π»Π΅ΠΊΠ΄ΠΆΠ΅ΠΊ ΠΈ ΠΊΡƒΡ€Ρ‚ΠΈΠ·Π°Π½ΠΊΠΈ, спаситСлни Π»ΠΈΠ½ΠΈΠΈ ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ.

Π’ΠΈΠ½Π°Π³ΠΈ Ρ‰Π΅ ΠΈΠΌΠ°ΠΌΠ΅ ΠΏΠΎΠ½Π΅ Π΅Π΄ΠΈΠ½ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π΅Π½ Ρ„Π°ΠΉΠ» ΠΈ масив ΠΎΡ‚ спаситСлни Π»ΠΈΠ½ΠΈΠΈ. Π‘Ρ…Π΅ΠΌΠ° вСрсия 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

UPS:
Какво ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ Π² Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚?
ΠŸΡŠΡ€Π²ΠΎ, Ρ€Π΅Π°Π»Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π·Π° Π°Π½Π°Π»ΠΈΠ·, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ тСстовСтС сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ Π² blazemeter ΠΈ Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π·Π° клиСнтскитС заявки Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ Π½Π΅ са ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΠ²Π½ΠΈ, Π·Π° Ρ€Π°Π·Π»ΠΈΠΊΠ° ΠΎΡ‚ чиститС HTTP заявки.

Π’Ρ‚ΠΎΡ€ΠΎ, ΠΏΡ€Π΅Ρ…ΠΎΠ΄ΡŠΡ‚ Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠΌ броя Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½ΠΈΡ‚Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ Π·Π° ΠΊΠ°Ρ‡Π²Π°Π½Π΅ Π½Π° Π΄ΠΎΠΊΠ΅Ρ€ΠΈ с ΠΎΠΊΠΎΠ»ΠΎ 150% ΠΈ Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ срСдно Π²Ρ€Π΅ΠΌΠ΅ Π·Π° рСакция с 20-25% ΠΏΠΎ-Π±ΡŠΡ€Π·ΠΎ. Π—Π° изтСглянС Π½Π° docker успяхмС Π΄Π° ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠΌ броя Π½Π° ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈΡ‚Π΅ с 500%, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ срСдното Π²Ρ€Π΅ΠΌΠ΅ Π·Π° рСакция намаля с ΠΎΠΊΠΎΠ»ΠΎ 60%.

Благодаря Π²ΠΈ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅Ρ‚ΠΎ.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€