рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдЧрд╡рддрд╛рдЪреНрдпрд╛ 2 рдкрд┐рд╢рд╡реНрдпрд╛, 75 рдореЗрд╕реНрдХрд▓рд╛рдЗрди рдЯреЕрдмреНрд▓реЗрдЯ рдпреБрдирд┐рдХреНрд╕ рд╡рд╛рддрд╛рд╡рд░рдг, рдПрдХ рдбреЙрдХрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдЖрдгрд┐ рдбреЙрдХрд░ рдХреНрд▓рд╛рдпрдВрдЯрд╢рд┐рд╡рд╛рдп рдбреЙрдХрд░ рдкреБрд▓ рдЖрдгрд┐ рдбреЙрдХрд░ рдкреБрд╢ рдХрдорд╛рдВрдбрдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдХрд░рдгреНрдпрд╛рдЪреЗ рдХрд╛рд░реНрдп рд╣реЛрддреЗ.
рдпреВрдкреАрдПрд╕:
рдкреНрд░рд╢реНрди: рд╣реЗ рд╕рд░реНрд╡ рдХрд╢рд╛рд╕рд╛рдареА рдЖрд╣реЗ?
рдЙрддреНрддрд░: рдЙрддреНрдкрд╛рджрдирд╛рдЪреА рд▓реЛрдб рдЪрд╛рдЪрдгреА (рдмреЕрд╢ рд╡рд╛рдкрд░рдд рдирд╛рд╣реА, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╢реИрдХреНрд╖рдгрд┐рдХ рд╣реЗрддреВрдВрд╕рд╛рдареА рдкреНрд░рджрд╛рди рдХреЗрд▓реНрдпрд╛ рдЖрд╣реЗрдд). рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реНрддрд░ (рд╡рд╛рдЬрд╡реА рдорд░реНрдпрд╛рджреЗрдд) рдХрдореА рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рддреНрдпрд╛рдиреБрд╕рд╛рд░, рдЙрдЪреНрдЪ рднрд╛рд░рд╛рдЪреЗ рдЕрдиреБрдХрд░рдг рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдбреЙрдХрд░ рдХреНрд▓рд╛рдпрдВрдЯрдЪрд╛ рд╡рд╛рдкрд░ рди рдХрд░рдгреНрдпрд╛рдЪрд╛ рдирд┐рд░реНрдгрдп рдШреЗрдгреНрдпрд╛рдд рдЖрд▓рд╛. рдкрд░рд┐рдгрд╛рдореА, рдбреЙрдХрд░ рдХреНрд▓рд╛рдпрдВрдЯрдЪреЗ рд╕рд░реНрд╡ рд╕рд┐рд╕реНрдЯрдо рд╡рд┐рд▓рдВрдм рдХрд╛рдврд▓реЗ рдЧреЗрд▓реЗ. рдЖрдореНрд╣рд╛рд▓рд╛ рдереЗрдЯ рдЙрддреНрдкрд╛рджрдирд╛рд╡рд░ рддреБрд▓рдиреЗрдиреЗ рд╕реНрд╡рдЪреНрдЫ рднрд╛рд░ рдорд┐рд│рд╛рд▓рд╛.
рд▓реЗрдЦрд╛рдд рд╕рд╛рдзрдирд╛рдВрдЪреНрдпрд╛ GNU рдЖрд╡реГрддреНрддреНрдпрд╛ рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЖрд╣реЗрдд.
рдкреНрд░рдердо, рдпрд╛ рдЖрдЬреНрдЮрд╛ рдХрд╛рдп рдХрд░рддрд╛рдд рддреЗ рд╢реЛрдзреВрдпрд╛.
рддрд░ рдбреЙрдХрд░ рдкреБрд▓ рдХрд╢рд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рддреЛ? рддреНрдпрд╛рдиреБрд╕рд╛рд░
"рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реАрдордзреВрди рдкреНрд░рддрд┐рдорд╛ рдХрд┐рдВрд╡рд╛ рднрд╛рдВрдбрд╛рд░ рдХрд╛рдврд╛".
рддреЗрдереЗ рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдХ рд▓рд┐рдВрдХ рджреЗрдЦреАрд▓ рдорд┐рд│рддреЗ
рдпреЗрдереВрди рдЖрдкрдг рд╕рдордЬреВ рд╢рдХрддреЛ рдХреА рдбреЙрдХрд░ рдкреНрд░рддрд┐рдорд╛ рд╣реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрддрд░рд╛рдВрдЪрд╛ рдПрдХ рд╕рдВрдЪ рдЖрд╣реЗ рдЬреНрдпрд╛рдордзреНрдпреЗ рдкреНрд░рддрд┐рдореЗрддреАрд▓ рдирд╡реАрдирддрдо рдмрджрд▓рд╛рдВрдмрджреНрджрд▓ рдорд╛рд╣рд┐рддреА рдЕрд╕рддреЗ, рдЬреА рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдкреБрдвреЗ рдЖрдкрдг рдкрд╛рд╣рддреЛ
рд╣реЗ рдЦрд╛рд▓реАрд▓ рдореНрд╣рдгрддреЗ:
"рдПрдХ "рдЗрдореЗрдЬ" рд╣реЗ 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"
рдкреНрд░рддрд┐рд╕рд╛рджрд╛рдд, рдЖрдореНрд╣рд╛рд▓рд╛ 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
рддреНрдпрд╛ рд░реЗрд▓ рд╣реЗ рдЯрд╛рд░ рдЖрд░реНрдХрд╛рдЗрд╡реНрд╣ рдЖрд╣реЗрдд, рддреНрдпрд╛рдВрдирд╛ рдпреЛрдЧреНрдп рдХреНрд░рдорд╛рдиреЗ рдЕрдирдкреЕрдХ рдХреЗрд▓реНрдпрд╛рд╕ рдЖрдореНрд╣рд╛рд▓рд╛ рдкреНрд░рддрд┐рдореЗрдЪреА рд╕рд╛рдордЧреНрд░реА рдорд┐рд│реЗрд▓.
рдЪрд▓рд╛ рдПрдХ рд▓рд╣рд╛рди рдмреЕрд╢ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рд╣реВ рдЬреЗрдгреЗрдХрд░реБрди рд╣реЗ рд╕рд░реНрд╡ рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдХрд░рддрд╛ рдпреЗрдИрд▓
#!/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
рднрд╛рдЧ реи - рдбреЙрдХрд░ рдкреБрд╢
рд╣реЗ рдереЛрдбреЗ рдЕрдзрд┐рдХ рдХреНрд▓рд┐рд╖реНрдЯ рд╣реЛрдИрд▓.
рдЪрд▓рд╛ рдкреБрдиреНрд╣рд╛ рд╕реБрд░реБрд╡рд╛рдд рдХрд░реВрдпрд╛
рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдгрд╛рдЪрд╛ рдЕрднреНрдпрд╛рд╕ рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, рдЖрдореНрд╣реА рдбрд╛рдЙрдирд▓реЛрдб рдкреНрд░рдХреНрд░рд┐рдпреЗрд▓рд╛ рдЕрдиреЗрдХ рдЪрд░рдгрд╛рдВрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЧреВ рд╢рдХрддреЛ:
- рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЖрд░рдВрдн - "POST /v2/{repoName}/blobs/uploads/"
- рд▓рд╛рдЗрдлрд▓рд╛рдЗрди рдЕрдкрд▓реЛрдб рдХрд░рдд рдЖрд╣реЗ (рдЖрдореНрд╣реА рдореЛрдиреЛрд▓рд┐рдерд┐рдХ рдЕрдкрд▓реЛрдб рд╡рд╛рдкрд░реВ, рдореНрд╣рдгрдЬреЗ рдЖрдореНрд╣реА рдкреНрд░рддреНрдпреЗрдХ рд▓рд╛рдИрдлрд▓рд╛рдИрди рд╕рдВрдкреВрд░реНрдгрдкрдгреЗ рдкрд╛рдард╡рддреЛ) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
рд╕рд╛рдордЧреНрд░реА-рд▓рд╛рдВрдмреА: {рд╕реНрддрд░рд╛рдЪрд╛ рдЖрдХрд╛рд░}
рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░: рдЕрдиреБрдкреНрд░рдпреЛрдЧ/рдСрдХреНрдЯреЗрдЯ-рд╕реНрдЯреНрд░реАрдо
рд▓реЗрдпрд░ рдмрд╛рдпрдирд░реА рдбреЗрдЯрд╛". - рдореЕрдирд┐рдлреЗрд╕реНрдЯ рд▓реЛрдб рдХрд░рдд рдЖрд╣реЗ - "PUT /v2/{repoName}/manifests/{reference}".
рдкрд░рдВрддреБ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг рдПрдХ рдкрд╛рдКрд▓ рдЪреБрдХрддреЗ, рддреНрдпрд╛рд╢рд┐рд╡рд╛рдп рдХрд╛рд╣реАрд╣реА рдХрд╛рд░реНрдп рдХрд░рдгрд╛рд░ рдирд╛рд╣реА. рдореЛрдиреЛрд▓рд┐рдерд┐рдХ рд▓реЛрдбрд┐рдВрдЧрд╕рд╛рдареА, рддрд╕реЗрдЪ рдЖрдВрд╢рд┐рдХ (рдЦрдВрдбрд┐рдд) рд╕рд╛рдареА, рд░реЗрд▓ рд▓реЛрдб рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА, рддреБрдореНрд╣реА рдкреЕрдЪ рд╡рд┐рдирдВрддреА рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ:
"рдкреЕрдЯрдЪ /v2/{repoName}/blobs/uploads/{uuid}
рд╕рд╛рдордЧреНрд░реА-рд▓рд╛рдВрдмреА: {рдЦрдВрдбрд╛рдЪрд╛ рдЖрдХрд╛рд░}
рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░: рдЕрдиреБрдкреНрд░рдпреЛрдЧ/рдСрдХреНрдЯреЗрдЯ-рд╕реНрдЯреНрд░реАрдо
{рд▓реЗрдпрд░ рдЪрдВрдХ рдмрд╛рдпрдирд░реА рдбреЗрдЯрд╛}".
рдЕрдиреНрдпрдерд╛, рддреБрдореНрд╣реА рдкрд╣рд┐рд▓реНрдпрд╛ рдмрд┐рдВрджреВрдЪреНрдпрд╛ рдкреБрдвреЗ рдЬрд╛рдК рд╢рдХрдгрд╛рд░ рдирд╛рд╣реА, рдХрд╛рд░рдг... рдЕрдкреЗрдХреНрд╖рд┐рдд рдкреНрд░рддрд┐рд╕рд╛рдж рдХреЛрдб 202 рдРрд╡рдЬреА, рддреБрдореНрд╣рд╛рд▓рд╛ 4xx рдкреНрд░рд╛рдкреНрдд рд╣реЛрдИрд▓.
рдЖрддрд╛ рдЕрд▓реНрдЧреЛрд░рд┐рджрдо рдЕрд╕реЗ рджрд┐рд╕рддреЗ:
- рдЖрд░рдВрдн
- рдкреЕрдЪ рд░реЗрд▓реНрд╡реЗ
- рд░реЗрд▓рд┐рдВрдЧ рд▓реЛрдб рдХрд░рдд рдЖрд╣реЗ
- рдореЕрдирд┐рдлреЗрд╕реНрдЯ рд▓реЛрдб рдХрд░рдд рдЖрд╣реЗ
рдмрд┐рдВрджреВ 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.0
рдпреВрдкреАрдПрд╕:
рдкрд░рд┐рдгрд╛рдореА рдЖрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рдорд┐рд│рд╛рд▓реЗ?
рдкреНрд░рдердо, рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рд╕рд╛рдареА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛, рдХрд╛рд░рдг рдЪрд╛рдЪрдгреНрдпрд╛ рдмреНрд▓реЗрдЭрдореАрдЯрд░рдордзреНрдпреЗ рдЪрд╛рд▓рд╡рд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдбреЙрдХрд░ рдХреНрд▓рд╛рдпрдВрдЯрдЪреНрдпрд╛ рд╡рд┐рдирдВрддреНрдпрд╛рдВрд╡рд░реАрд▓ рдбреЗрдЯрд╛ рд╢реБрджреНрдз HTTP рд╡рд┐рдирдВрддреНрдпрд╛рдВрдкреНрд░рдорд╛рдгреЗ рдлрд╛рд░рд╕рд╛ рдорд╛рд╣рд┐рддреАрдкреВрд░реНрдг рдирд╕рддреЛ.
рджреБрд╕рд░реЗ рдореНрд╣рдгрдЬреЗ, рд╕рдВрдХреНрд░рдордгрд╛рдиреЗ рдЖрдореНрд╣рд╛рд▓рд╛ рдбреЙрдХрд░ рдЕрдкрд▓реЛрдбрд╕рд╛рдареА рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдВрдЪреА рд╕рдВрдЦреНрдпрд╛ рд╕реБрдорд╛рд░реЗ 150% рдиреЗ рд╡рд╛рдврд╡рдгреНрдпрд╛рдЪреА рдЖрдгрд┐ рд╕рд░рд╛рд╕рд░реА рдкреНрд░рддрд┐рд╕рд╛рдж рд╡реЗрд│ 20-25% рдЬрд▓рдж рдорд┐рд│рд╡рд┐рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджрд┐рд▓реА. рдбреЙрдХрд░ рдбрд╛рдЙрдирд▓реЛрдбрд╕рд╛рдареА, рдЖрдореНрд╣реА рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдВрдЪреА рд╕рдВрдЦреНрдпрд╛ 500% рд╡рд╛рдврд╡рд┐рдгреНрдпрд╛рдд рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ, рддрд░ рд╕рд░рд╛рд╕рд░реА рдкреНрд░рддрд┐рд╕рд╛рдж рд╡реЗрд│ рд╕реБрдорд╛рд░реЗ 60% рдиреЗ рдХрдореА рдЭрд╛рд▓рд╛.
рдЖрдкрд▓реНрдпрд╛ рд▓рдХреНрд╖ рджрд┐рд▓реНрдпрд╛рдмрджреНрджрд▓ рдзрдиреНрдпрд╡рд╛рдж.
рд╕реНрддреНрд░реЛрдд: www.habr.com