HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

์šฐ๋ฆฌ๋Š” 2๊ฐœ์˜ ํ’€ ๋ด‰์ง€, 75๊ฐœ์˜ ๋ฉ”์Šค์นผ๋ฆฐ ํƒœ๋ธ”๋ฆฟ Unix ํ™˜๊ฒฝ, ๋„์ปค ์ €์žฅ์†Œ, ๊ทธ๋ฆฌ๊ณ  ๋„์ปค ํด๋ผ์ด์–ธํŠธ ์—†์ด ๋„์ปค ํ’€ ๋ฐ ๋„์ปค ํ‘ธ์‹œ ๋ช…๋ น์„ ๊ตฌํ˜„ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

UPD :
์งˆ๋ฌธ: ์ด ๋ชจ๋“  ๊ฒƒ์€ ๋ฌด์—‡์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๊นŒ?
๋‹ต๋ณ€: ์ œํ’ˆ์˜ ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ(bash๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์Šคํฌ๋ฆฝํŠธ๋Š” ๊ต์œก ๋ชฉ์ ์œผ๋กœ ์ œ๊ณต๋จ) ์ถ”๊ฐ€ ๋ ˆ์ด์–ด๋ฅผ ์ค„์ด๊ณ (ํ•ฉ๋ฆฌ์ ์ธ ํ•œ๋„ ๋‚ด์—์„œ) ๊ทธ์— ๋”ฐ๋ผ ๋” ๋†’์€ ๋กœ๋“œ๋ฅผ ์—๋ฎฌ๋ ˆ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด Docker ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ Docker ํด๋ผ์ด์–ธํŠธ์˜ ๋ชจ๋“  ์‹œ์Šคํ…œ ์ง€์—ฐ์ด ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ œํ’ˆ์— ์ง์ ‘ ๋น„๊ต์  ๊นจ๋—ํ•œ ํ•˜์ค‘์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
์ด ๊ธฐ์‚ฌ์—์„œ๋Š” GNU ๋ฒ„์ „์˜ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ €, ์ด ๋ช…๋ น๋“ค์ด ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด docker pull์€ ์–ด๋””์— ์‚ฌ์šฉ๋˜๋‚˜์š”? ์— ๋”ฐ๋ฅด๋ฉด ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜:

"๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์ด๋ฏธ์ง€ ๋˜๋Š” ์ €์žฅ์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ".

๊ฑฐ๊ธฐ์—๋Š” ๋‹ค์Œ ๋งํฌ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€, ์ปจํ…Œ์ด๋„ˆ, ์Šคํ† ๋ฆฌ์ง€ ๋“œ๋ผ์ด๋ฒ„ ์ดํ•ด.

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

์—ฌ๊ธฐ์—์„œ ์šฐ๋ฆฌ๋Š” ๋„์ปค ์ด๋ฏธ์ง€๊ฐ€ ์ด๋ฏธ์ง€์˜ ์ตœ์‹  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ํŠน์ • ๋ ˆ์ด์–ด ์„ธํŠธ๋ผ๋Š” ๊ฒƒ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ถ„๋ช…ํžˆ ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ API.

๊ทธ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ•ฉ๋‹ˆ๋‹ค :

""์ด๋ฏธ์ง€"๋Š” JSON ๋งค๋‹ˆํŽ˜์ŠคํŠธ์™€ ๊ฐœ๋ณ„ ๋ ˆ์ด์–ด ํŒŒ์ผ์˜ ์กฐํ•ฉ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ”„๋กœ์„ธ์Šค๋Š” ์ด ๋‘ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค."

๋”ฐ๋ผ์„œ ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” โ€œ์ด๋ฏธ์ง€ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ".

๋ฌผ๋ก  ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์˜์ง€๋Š” ์•Š์„ ๊ฒƒ์ด์ง€๋งŒ ๊ทธ๊ฒƒ์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์š”์ฒญ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. GET /v2/{name}/manifests/{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"

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

์ด์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ ์ƒ๋ช…์„ ์ด๋‚˜ ํ•ด์‹œ์—๋งŒ ๊ด€์‹ฌ์ด ์žˆ๋Š” 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 ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

์ฒซ ๋ฒˆ์งธ ์ƒ๋ช…์„ ์œผ๋กœ ์ตœ์ข…์ ์œผ๋กœ ์–ด๋–ค ํŒŒ์ผ์„ ๋ฐ›์•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

file firstLayer

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

์ €๊ฒƒ๋“ค. ๋ ˆ์ผ์€ 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}
    ์ฝ˜ํ…์ธ  ๊ธธ์ด: {๋ ˆ์ด์–ด ํฌ๊ธฐ}
    ์ฝ˜ํ…์ธ  ์œ ํ˜•: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜/์˜ฅํ…Ÿ ์ŠคํŠธ๋ฆผ
    ๋ ˆ์ด์–ด ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ'๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
  • ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๋กœ๋“œ ์ค‘ - "PUT /v2/{repoName}/manifests/{reference}".

๊ทธ๋Ÿฌ๋‚˜ ๋ฌธ์„œ์—๋Š” ํ•œ ๋‹จ๊ณ„๊ฐ€ ๋น ์ ธ ์žˆ์œผ๋ฉฐ, ์ด ๋‹จ๊ณ„๊ฐ€ ์—†์œผ๋ฉด ์•„๋ฌด ๊ฒƒ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋†€๋ฆฌ์‹ ๋กœ๋”ฉ๊ณผ ๋ถ€๋ถ„(์ฒญํฌ) ๋กœ๋”ฉ์˜ ๊ฒฝ์šฐ ๋ ˆ์ผ์„ ๋กœ๋”ฉํ•˜๊ธฐ ์ „์— PATCH ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

"ํŒจ์น˜ /v2/{repoName}/blobs/uploads/{uuid}
์ฝ˜ํ…์ธ  ๊ธธ์ด: {์ฒญํฌ ํฌ๊ธฐ}
์ฝ˜ํ…์ธ  ์œ ํ˜•: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜/์˜ฅํ…Ÿ ์ŠคํŠธ๋ฆผ
{๋ ˆ์ด์–ด ์ฒญํฌ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ}".

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ฒซ ๋ฒˆ์งธ ์ง€์ ์„ ๋„˜์–ด ์ด๋™ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด... ์˜ˆ์ƒ๋˜๋Š” ์‘๋‹ต ์ฝ”๋“œ 202 ๋Œ€์‹  4xx๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ดˆ๊ธฐํ™”
  • ํŒจ์น˜ ๋ ˆ์ผ
  • ๋‚œ๊ฐ„ ๋กœ๋“œ
  • ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๋กœ๋“œ ์ค‘
    ํฌ์ธํŠธ 2์™€ 3์€ ๊ฐ๊ฐ ๋กœ๋“œํ•ด์•ผ ํ•˜๋Š” ๋ผ์ธ ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค.

๋จผ์ € ์ด๋ฏธ์ง€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” Archlinux:latest๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

docker pull archlinux

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

์ด์ œ ์ถ”๊ฐ€ ๋ถ„์„์„ ์œ„ํ•ด ๋กœ์ปฌ์— ์ €์žฅํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

docker save c24fe13d37b9 -o savedArch

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

๊ฒฐ๊ณผ ์•„์นด์ด๋ธŒ๋ฅผ ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์— ์••์ถ• ํ•ด์ œ

tar xvf savedArch

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

๋ณด์‹œ๋‹ค์‹œํ”ผ, ๊ฐ ์ƒ๋ช…์„ ์€ ๋ณ„๋„์˜ ํด๋”์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ›์€ ๋งค๋‹ˆํŽ˜์ŠคํŠธ์˜ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

cat manifest.json | json_pp

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

๋ณ„๋กœ. ๋กœ๋“œํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜.

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ docker ํด๋ผ์ด์–ธํŠธ ์—†์ด docker pull ๋ฐ docker push ๋ช…๋ น ๊ตฌํ˜„

๋ถ„๋ช…ํžˆ ๊ธฐ์กด ์„ ์–ธ๋ฌธ์€ ์šฐ๋ฆฌ์—๊ฒŒ ์ ํ•ฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ธ”๋ž™์žญ๊ณผ ์ฐฝ๋…€, ์ƒ๋ช…์„  ๋ฐ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์šฐ๋ฆฌ๋งŒ์˜ ์„ ์–ธ๋ฌธ์„ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ๊ตฌ์„ฑ ํŒŒ์ผ๊ณผ ์ผ๋ จ์˜ ์ƒ๋ช…์„ ์„ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑํ‘œ ๋ฒ„์ „ 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์—์„œ ์‹คํ–‰๋˜๊ณ  docker ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋Š” ์ˆœ์ˆ˜ํ•œ HTTP ์š”์ฒญ๊ณผ ๋‹ฌ๋ฆฌ ๊ทธ๋‹ค์ง€ ์œ ์ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‘˜์งธ, ์ „ํ™˜์„ ํ†ตํ•ด Docker ์—…๋กœ๋“œ๋ฅผ ์œ„ํ•œ ๊ฐ€์ƒ ์‚ฌ์šฉ์ž ์ˆ˜๊ฐ€ ์•ฝ 150% ์ฆ๊ฐ€ํ•˜๊ณ  ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„์ด 20-25% ๋” ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค. Docker ๋‹ค์šด๋กœ๋“œ์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ์ˆ˜๋Š” 500% ์ฆ๊ฐ€ํ•œ ๋ฐ˜๋ฉด ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„์€ ์•ฝ 60% ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ด€์‹ฌ์„ ๊ฐ€์ ธ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€