Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Sasinezikhwama zotshani ezingu-2, imvelo yamaphilisi e-mescaline angu-75 unix, indawo yokugcina impahla kanye nomsebenzi wokusebenzisa imiyalo yokudonsa kwedokhu kanye ne-docker push ngaphandle kweklayenti le-docker.

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

I-UPS:
Umbuzo: Kwenzelweni konke lokhu?
Impendulo: Ukuhlolwa komthwalo womkhiqizo (HHAYI ukusebenzisa i-bash, imibhalo inikezwe izinjongo zokufundisa). Kunqunywe ukuthi kungasebenzisi iklayenti le-docker ukunciphisa izendlalelo ezengeziwe (ngaphakathi kwemikhawulo enengqondo) futhi, ngokufanele, ukulingisa umthwalo ophezulu. Ngenxa yalokho, konke ukubambezeleka kwesistimu yeklayenti le-Docker kususiwe. Sithole umthwalo ohlanzekile uma kuqhathaniswa ngqo emkhiqizweni.
I-athikili isebenzise izinguqulo ze-GNU zamathuluzi.

Okokuqala, ake sithole ukuthi le miyalo yenzani.

Ngakho-ke i-docker pull isetshenziselwa ini? Ngokuvumelana ne imibhalo:

"Donsa isithombe noma indawo yokugcina endaweni yokubhalisa".

Lapho siphinde sithole isixhumanisi esiya qonda izithombe, iziqukathi, nabashayeli besitoreji.

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Kusuka lapha singaqonda ukuthi isithombe se-docker siyisethi yezendlalelo ezithile eziqukethe ulwazi mayelana nezinguquko zakamuva esithombeni, okusobala ukuthi yilokho esikudingayo. Okulandelayo sibheka i-registry API.

Ithi okulandelayo:

"Isithombe" siyinhlanganisela ye-JSON manifest kanye namafayela wesendlalelo ngasinye. Inqubo yokudonsa > isithombe igxile ekutholeni lezi zingxenye ezimbili."

Ngakho-ke isinyathelo sokuqala ngokusho kwemibhalo sithi β€œUkudonsa i-Manifest yesithombe".

Yiqiniso, ngeke siyidubule, kodwa sidinga idatha kuyo. Okulandelayo isicelo esiyisibonelo: GET /v2/{name}/manifests/{reference}

"Igama nepharamitha yereferensi ikhomba isithombe futhi iyadingeka. Isithenjwa singafaka umaka noma inhlabamkhosi."

Inqolobane yethu yedokodo isetshenziswa endaweni, ake sizame ukwenza isicelo:

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

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Ngempendulo, sithola i-json lapho okwamanje sinentshisekelo kuphela emigqeni yokuphila, noma kunalokho ama-hashi abo. Ngemva kokuwathola, singangena kuso ngasinye bese sifaka isicelo esilandelayo: "THOLA /v2/{name}/blobs/{digest}"

"Ukufinyelela kwesendlalelo kuzofakwa kusango ngegama lenqolobane kodwa kukhonjwa ngokukhethekile ekubhaliseni ngenhlabamkhosi."

inhlabamkhosi kuleli cala ihashi esilitholile.

Ake sizame

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

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Ake sibone ukuthi hlobo luni lwefayela esigcine silitholile njengomugqa wokuqala wokuphila.

file firstLayer

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

labo. ojantshi bayizinqolobane zetiyela, sizikhipha ngendlela efanele sizothola okuqukethwe kwesithombe.

Masibhale umbhalo omncane we-bash ukuze konke lokhu kuzenzekele

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

Manje singayiqhuba ngemingcele oyifunayo futhi sithole okuqukethwe kwesithombe esidingekayo

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

Ingxenye 2 - i-docker push

Lokhu kuzoba inkimbinkimbi kancane.

Ake siqale futhi imibhalo. Ngakho-ke sidinga ukulanda umholi ngamunye, siqoqe i-manifest ehambisanayo futhi siyilande futhi. Kubonakala kulula.

Ngemva kokutadisha imibhalo, singahlukanisa inqubo yokukhipha ibe yizinyathelo ezimbalwa:

  • Ukuqaliswa kwenqubo - "THUMELA /v2/{repoName}/blobs/uploads/"
  • Ukulayisha umugqa wempilo (sizosebenzisa ukulayisha okukodwa, okungukuthi sithumela umugqa wempilo ngamunye uwonke) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
    Ubude Bokuqukethwe: {size of layer}
    Uhlobo Lokuqukethwe: isicelo/octet-stream
    Isendlalelo sedatha kanambambili".
  • Ilayisha i-manifest - "PUT /v2/{repoName}/manifests/{reference}".

Kodwa imibhalo igeja isinyathelo esisodwa, ngaphandle kwalokho akukho okuzosebenza. Ukuze ulayishe i-monolithic, kanye nengxenye (i-chunked), ngaphambi kokulayisha ujantshi, kufanele wenze isicelo se-PATCH:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
Ubude Bokuqukethwe: {size of chunk}
Uhlobo Lokuqukethwe: isicelo/octet-stream
{Layer Chunk Binary Data}".

Uma kungenjalo, ngeke ukwazi ukudlulela ngale kwephuzu lokuqala, ngoba... Esikhundleni sekhodi elindelekile yokuphendula engu-202, uzothola i-4xx.

Manje i-algorithm ibukeka kanje:

  • Ukuqalisa
  • Umzila wesitimela
  • Ilayisha i-handrail
  • Ilayisha i-manifest
    Amaphuzu 2 no-3, ngokulandelana, azophindwa izikhathi eziningi njengoba inani lemigqa lidinga ukulayishwa.

Okokuqala, sidinga noma yisiphi isithombe. Ngizosebenzisa i-archlinux:yakamuva

docker pull archlinux

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Manje masiyilondoloze endaweni ukuze ihlaziywe okwengeziwe

docker save c24fe13d37b9 -o savedArch

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Khipha ingobo yomlando ewumphumela kuhla lwemibhalo lwamanje

tar xvf savedArch

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Njengoba ubona, umugqa wempilo ngamunye ukufolda ehlukile. Manje ake sibheke ukwakheka kwe-manifest esiyitholile

cat manifest.json | json_pp

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Akukho kuningi. Ake sibone ukuthi iyiphi i-manifest edingekayo ukuze ilayishe, ngokusho imibhalo.

Isebenzisa imiyalo yokudonsa kanye ne-docker push ngaphandle kweklayenti le-docker lisebenzisa izicelo ze-HTTP

Ngokusobala, i-manifesto ekhona ayihambisani nathi, ngakho-ke sizozenzela okwethu nge-blackjack nama-courtesans, imigqa yokuphila kanye nezilungiselelo.

Sizohlala sinefayela okungenani elilodwa lokucushwa kanye noxhaxha lwemigqa yokuphila. Inguqulo yesi-2 (yamanje ngesikhathi sokubhala), i-mediaType izoshiywa ingashintshiwe:

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

Ngemva kokudala i-manifest eyisisekelo, udinga ukuyigcwalisa ngedatha evumelekile. Ukwenza lokhu, sisebenzisa ithempulethi ye-json yento yesitimela:

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

Sizokwengeza ku-manifest yesitimela ngasinye.

Okulandelayo, sidinga ukuthola usayizi wefayela lokumisa bese sibuyisela ama-stubs ku-manifest ngedatha yangempela

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

Manje usungakwazi ukuqalisa inqubo yokukhipha futhi uzigcinele i-uuid, okufanele ihambisane nazo zonke izicelo ezilandelayo.

Umbhalo ophelele ubukeka kanjena:

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

singasebenzisa iskripthi esenziwe ngomumo:

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

I-UPS:
Sitholeni ngenxa yalokho?
Okokuqala, idatha yangempela yokuhlaziywa, njengoba ukuhlolwa kwenziwa nge-blazemeter futhi idatha yezicelo zeklayenti le-docker ayinalo ulwazi kakhulu, ngokungafani nezicelo ze-HTTP ezimsulwa.

Okwesibili, inguquko isivumele ukuthi sinyuse inani labasebenzisi ababonakalayo bokulayisha idokhu cishe ngo-150% futhi sithole isikhathi sokuphendula esimaphakathi esingu-20-25% ngokushesha. Ngokulanda i-docker, sikwazile ukukhulisa inombolo yabasebenzisi ngo-500%, kanti isikhathi sokuphendula esimaphakathi sehle ngo-60%.

Ngiyabonga ngokunaka kwakho.

Source: www.habr.com

Engeza amazwana