Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Nou te gen 2 sache zèb, 75 tablèt mescaline anviwònman UNIX, yon depo docker ak travay pou mete ann aplikasyon docker pull ak docker push kòmandman san yon kliyan docker.

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

UPS:
Kesyon: Pou kisa tout bagay sa yo ye?
Repons: Tès chaj pwodwi a (PA itilize bash, yo bay scripts yo pou rezon edikasyon). Li te deside pa sèvi ak kliyan an Docker diminye kouch adisyonèl (nan limit rezonab) epi, kòmsadwa, imite yon chaj ki pi wo. Kòm yon rezilta, tout reta sistèm nan kliyan an Docker yo te retire. Nou te resevwa yon chaj relativman pwòp dirèkteman sou pwodwi a.
Atik la te itilize vèsyon GNU nan zouti.

Premyèman, ann chèche konnen kisa kòmandman sa yo fè.

Se konsa, ki sa ki docker pull itilize pou? Dapre dokiman:

"Rale yon imaj oswa yon depo soti nan yon rejis".

La nou jwenn tou yon lyen pou konprann imaj, resipyan, ak chofè depo.

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Soti isit la nou ka konprann ke yon imaj docker se yon seri kouch sèten ki gen enfòmasyon sou dènye chanjman nan imaj la, ki se evidamman sa nou bezwen. Apre sa nou gade API rejis.

Li di sa ki annapre yo:

"Yon "imaj" se yon konbinezon de yon manifest JSON ak dosye kouch endividyèl. Pwosesis la nan rale yon > sant imaj alantou rekipere de eleman sa yo."

Se konsa, premye etap la dapre dokiman an se "Rale yon manifès imaj".

Natirèlman, nou pa pral tire li, men nou bezwen done ki soti nan li. Sa ki anba la a se yon egzanp demann: GET /v2/{name}/manifests/{reference}

"Non an ak paramèt referans idantifye imaj la epi yo obligatwa. Referans lan ka gen ladan yon tag oswa dijere."

Repozitwa docker nou an deplwaye lokalman, ann eseye egzekite demann lan:

curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/manifests/1.1.1" -H "header_if_needed"

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Kòm repons, nou resevwa json ki soti nan ki kounye a nou se sèlman enterese nan liy lavi yo, oswa pito hash yo. Lè nou resevwa yo, nou ka ale nan chak yo epi egzekite demann sa a: "GET /v2/{name}/blobs/{digest}"

"Aksè a yon kouch pral fèmen pa non an nan depo a men yo idantifye inikman nan rejis la pa dijere."

dijere nan ka sa a se hash ke nou te resevwa.

Eseye

curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/blobs/sha256:f972d139738dfcd1519fd2461815651336ee25a8b54c358834c50af094bb262f" -H "header_if_needed" --output firstLayer

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Ann wè ki kalite fichye finalman nou te resevwa kòm premye liy lavi a.

file firstLayer

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

sa yo. ray yo se achiv goudwon, debalaj yo nan lòd ki apwopriye a nou pral jwenn sa ki nan imaj la.

Ann ekri yon ti script bash pou tout bagay sa yo ka otomatize

#!/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

Koulye a, nou ka kouri li ak paramèt yo vle epi jwenn sa ki nan imaj ki nesesè yo

./script.sh dirName “http://localhost:8081/link/to/docker/registry” myAwesomeImage 1.0

Pati 2 - Docker pouse

Sa a pral yon ti kras pi konplike.

Ann kòmanse ankò ak dokiman. Se konsa, nou bezwen telechaje chak lidè, kolekte manifest ki koresponn lan epi telechaje li tou. Li sanble senp.

Apre w fin etidye dokiman an, nou ka divize pwosesis download la an plizyè etap:

  • Pwosesis inisyalizasyon - "POST /v2/{repoName}/blobs/uploads/"
  • Téléchargement yon liy sovtaj (nou pral sèvi ak yon telechajman monolitik, sa vle di nou voye chak liy lavi an antye) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
    Longè kontni: {gwosè kouch}
    Content-Tip: aplikasyon/octet-stream
    Kouch Done Binè".
  • Chaje manifest la - "PUT /v2/{repoName}/manifests/{reference}".

Men, dokimantasyon an manke yon etap, san yo pa gen anyen ki pral travay. Pou chaje monolitik, osi byen ke pou yon pati nan (yon moso), anvan ou chaje tren an, ou dwe fè yon demann PATCH:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
Longè kontni: {gwosè moso}
Content-Tip: aplikasyon/octet-stream
{Kouch Chunk Done Binè}".

Sinon, ou p'ap ka deplase pi lwen pase premye pwen an, paske... Olye de kòd repons espere 202, w ap resevwa 4xx.

Koulye a, algorithm la sanble:

  • Inisyalizasyon
  • Patch tren
  • Chaje ranp lan
  • Chaje manifest la
    Pwen 2 ak 3, respektivman, ap repete otan fwa kantite liy yo bezwen chaje.

Premyèman, nou bezwen nenpòt imaj. Mwen pral sèvi ak archlinux:latest

docker pull archlinux

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Koulye a, kite a sove li lokalman pou plis analiz

docker save c24fe13d37b9 -o savedArch

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Depake achiv ki kapab lakòz yo nan anyè aktyèl la

tar xvf savedArch

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Kòm ou ka wè, chak liy lavi se nan yon katab separe. Koulye a, ann gade nan estrikti a nan manifest nou te resevwa a

cat manifest.json | json_pp

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Pa anpil. Ann wè ki manifest ki nesesè pou chaje, selon dokiman.

Aplike docker pull ak docker push kòmandman san yon kliyan docker itilize HTTP demann

Li evidan, manifeste ki deja egziste a pa adapte nou, kidonk nou pral fè pwòp pa nou ak blakjak ak kourtizan, liy lavi ak konfigirasyon.

N ap toujou gen omwen yon fichye konfigirasyon ak yon seri liy lavi. Vèsyon Scheme 2 (aktyèl nan moman w ap ekri a), mediaType ap rete san chanjman:

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

Apre ou fin kreye manifest debaz la, ou bezwen ranpli li ak done ki valab. Pou fè sa, nou itilize modèl json objè tren an:

{
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": ${layersSizes[$i]},
         "digest": "sha256:${layersNames[$i]}"
      },

Nou pral ajoute li nan manifest pou chak ray.

Apre sa, nou bezwen chèche konnen gwosè a nan fichye a konfigirasyon epi ranplase souch yo nan manifest la ak done reyèl

sed -i "s/config_size/$configSize/g; s/config_hash/$configName/g" $manifestFile

Koulye a, ou ka kòmanse pwosesis download la epi sove tèt ou yon uuid, ki ta dwe akonpaye tout demann ki vin apre yo.

Script konplè a sanble yon bagay tankou sa a:

#!/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

nou ka itilize yon script ki pare:

./uploadImage.sh "~/path/to/saved/image" "http://localhost:8081/link/to/docker/registry" myRepoName 1.0

UPS:
Ki sa nou te jwenn kòm yon rezilta?
Premyèman, done reyèl pou analiz, depi tès yo kouri nan blazemeter ak done yo sou demann kliyan Docker yo pa trè enfòmatif, kontrèman ak pi bon kalite demann HTTP.

Dezyèmman, tranzisyon an te pèmèt nou ogmante kantite itilizatè vityèl pou telechaje docker pa apeprè 150% epi jwenn tan repons mwayèn 20-25% pi vit. Pou telechajman Docker, nou jere ogmante kantite itilizatè yo pa 500%, pandan y ap tan repons mwayèn diminye pa apeprè 60%.

Mèsi pou atansyon ou.

Sous: www.habr.com

Add nouvo kòmantè