L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Kellna 2 boroż ta 'ħaxix, 75 mescaline tablets unix environment, repożitorju ta' docker u l-kompitu li nimplimentaw il-kmandi ta 'docker pull u docker push mingħajr klijent docker.

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

AĠĠORNAMENT:
Mistoqsija: Dan kollu għal xiex?
Tweġiba: Ittestjar tat-tagħbija tal-prodott (MHUX tuża bash, l-iskripts huma pprovduti għal skopijiet edukattivi). Ġie deċiż li ma jintużax il-klijent docker biex jitnaqqsu saffi addizzjonali (f'limiti raġonevoli) u, għaldaqstant, jimitaw tagħbija ogħla. Bħala riżultat, id-dewmien kollu tas-sistema tal-klijent Docker tneħħa. Irċevejna tagħbija relattivament nadifa direttament fuq il-prodott.
L-artiklu uża verżjonijiet GNU tal-għodod.

L-ewwel, ejja nsemmu x'jagħmlu dawn il-kmandi.

Allura għalxiex tintuża docker pull? Skond dokumentazzjoni:

"Iġbed immaġni jew repożitorju minn reġistru".

Hemm insibu wkoll link għal tifhem immaġini, kontenituri, u sewwieqa tal-ħażna.

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Minn hawn nistgħu nifhmu li immaġni docker hija sett ta 'ċerti saffi li fihom informazzjoni dwar l-aħħar bidliet fl-immaġni, li ovvjament huwa dak li għandna bżonn. Sussegwentement inħarsu lejn API tar-reġistru.

Jgħid dan li ġej:

""Immaġini" hija kombinazzjoni ta 'manifest JSON u fajls ta' saff individwali. Il-proċess ta 'ġbid ta' > immaġni jiffoka fuq l-irkupru ta 'dawn iż-żewġ komponenti."

Allura l-ewwel pass skont id-dokumentazzjoni huwa "Ġbid ta' Manifest tal-Immaġni".

Naturalment, mhux se nisparawh, iżda għandna bżonn id-dejta minnha. Din li ġejja hija talba eżempju: GET /v2/{name}/manifests/{reference}

"L-isem u l-parametru ta 'referenza jidentifikaw l-immaġni u huma meħtieġa. Ir-referenza tista' tinkludi tikketta jew diġest."

Ir-repożitorju tad-docker tagħna huwa skjerat lokalment, ejja nippruvaw tesegwixxi t-talba:

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

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Bi tweġiba, nirċievu json li minnu bħalissa ninsabu interessati biss fil-linji tas-salvataġġ, jew aħjar il-hashes tagħhom. Wara li rċevejnahom, nistgħu ngħaddu minn kull waħda u nwettqu t-talba li ġejja: "GET /v2/{name}/blobs/{digest}"

"L-aċċess għal saff se jkun imqabbad mill-isem tar-repożitorju iżda huwa identifikat unikament fir-reġistru permezz tad-diġest."

diġest f'dan il-każ huwa l-hash li rċevejna.

Ejja nipruvaw

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

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Ejja naraw x'tip ta 'fajl fl-aħħar irċevejna bħala l-ewwel linja ta' salvataġġ.

file firstLayer

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

dawk. il-binarji huma arkivji tal-qatran, li tħollhom fl-ordni xierqa se nġibu l-kontenut tal-immaġni.

Ejja niktbu script bash żgħir sabiex dan kollu jkun jista 'jiġi awtomatizzat

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

Issa nistgħu nħaddmuha bil-parametri mixtieqa u niksbu l-kontenut tal-immaġni meħtieġa

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

Parti 2 - docker push

Dan se jkun ftit aktar ikkumplikat.

Ejja nerġgħu nibdew bi dokumentazzjoni. Għalhekk irridu tniżżel kull mexxej, niġbru l-manifest korrispondenti u niżżlu wkoll. Jidher sempliċi.

Wara li nistudjaw id-dokumentazzjoni, nistgħu naqsmu l-proċess tat-tniżżil f'diversi passi:

  • Inizjalizzazzjoni tal-proċess - "POST /v2/{repoName}/blobs/uploads/"
  • Tlugħ ta' linja ta' salvataġġ (se nużaw upload monolitiku, jiġifieri nibagħtu kull linja ta' salvataġġ fl-intier tagħha) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
    Content-Length: {daqs tas-saff}
    Tip ta' Kontenut: applikazzjoni/octet-stream
    Saff tad-Data Binarja".
  • Tagħbija l-manifest - "PUT /v2/{repoName}/manifests/{reference}".

Iżda d-dokumentazzjoni titlef pass wieħed, li mingħajru xejn ma jaħdem. Għat-tagħbija monolitika, kif ukoll għal parzjali (bċ-biċċiet), qabel it-tagħbija tal-ferrovija, trid twettaq talba PATCH:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
Content-Length: {daqs tal-biċċa}
Tip ta' Kontenut: applikazzjoni/octet-stream
{Layer Chunk Binary Data}".

Inkella, ma tkunx tista' timxi lil hinn mill-ewwel punt, għax... Minflok il-kodiċi tar-rispons mistenni 202, tirċievi 4xx.

Issa l-algoritmu jidher bħal:

  • Inizjalizzazzjoni
  • Ferrovija tal-garża
  • Tagħbija tal-poġġaman
  • Tagħbija tal-manifest
    Il-punti 2 u 3, rispettivament, se jiġu ripetuti kemm-il darba n-numru ta' linji jeħtieġ li jitgħabbew.

L-ewwel, għandna bżonn kwalunkwe immaġini. Se nuża archlinux:latest

docker pull archlinux

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Issa ejja nsalvawh lokalment għal aktar analiżi

docker save c24fe13d37b9 -o savedArch

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Spakkja l-arkivju li jirriżulta fid-direttorju attwali

tar xvf savedArch

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Kif tistgħu taraw, kull linja ta 'salvataġġ tinsab f'folder separat. Issa ejja nħarsu lejn l-istruttura tal-manifest li rċevejna

cat manifest.json | json_pp

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Mhux hafna. Ejja naraw liema manifest huwa meħtieġ għat-tagħbija, skond dokumentazzjoni.

L-implimentazzjoni ta' docker pull u docker push kmandi mingħajr klijent docker bl-użu ta' talbiet HTTP

Ovvjament, il-manifest eżistenti ma jixraqx lilna, għalhekk aħna se nagħmlu tagħna stess bil-blackjack u courtesans, lifelines u configs.

Dejjem ikollna mill-inqas fajl wieħed ta' konfigurazzjoni u firxa ta' linji ta' salvataġġ. Verżjoni tal-iskema 2 (kurrenti fil-ħin tal-kitba), mediaType se titħalla mhux mibdula:

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

Wara li toħloq il-manifest bażiku, trid timlah b'dejta valida. Biex tagħmel dan, nużaw il-mudell json tal-oġġett tal-ferrovija:

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

Aħna se nżiduha mal-manifest għal kull ferrovija.

Sussegwentement, għandna bżonn insibu d-daqs tal-fajl tal-konfigurazzjoni u nibdlu l-stubs fil-manifest b'dejta reali

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

Issa tista 'tibda l-proċess tat-tniżżil u tiffranka lilek innifsek uuid, li għandu jakkumpanja t-talbiet kollha sussegwenti.

L-iskrittura kompluta tidher xi ħaġa bħal din:

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

nistgħu nużaw skript lest:

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

AĠĠORNAMENT:
X’ksibna bħala riżultat?
L-ewwelnett, dejta reali għall-analiżi, peress li t-testijiet jitmexxew f'blazemeter u d-dejta dwar it-talbiet tal-klijenti docker mhijiex informattivi ħafna, b'differenza mit-talbiet HTTP puri.

It-tieni, it-tranżizzjoni ppermettietna nżidu n-numru ta 'utenti virtwali għat-tlugħ ta' docker b'madwar 150% u niksbu ħin ta 'rispons medju 20-25% aktar malajr. Għat-tniżżil ta' docker, irnexxielna nżidu n-numru ta' utenti b'500%, filwaqt li l-ħin medju ta' rispons naqas b'madwar 60%.

Grazzi għall-attenzjoni tiegħek.

Sors: www.habr.com

Żid kumment