Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Muna da jakunkuna 2 na ciyawa, 75 mescaline allunan unix muhalli, wurin ajiyar docker da aikin aiwatar da docker ja da docker tura umarnin ba tare da docker abokin ciniki.

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

UPS:
Tambaya: Menene duk wannan?
Amsa: Gwajin lodi na samfurin (BA a amfani da bash ba, an samar da rubutun don dalilai na ilimi). An yanke shawarar kada a yi amfani da abokin aikin docker don rage ƙarin yadudduka (a cikin iyakoki masu ma'ana) kuma, bisa ga haka, yin koyi da babban nauyi. Sakamakon haka, an cire duk jinkirin tsarin abokin ciniki na Docker. Mun sami kaya mai tsabta kai tsaye akan samfurin.
Labarin ya yi amfani da nau'ikan kayan aikin GNU.

Da farko, bari mu gano abin da waɗannan umarnin suke yi.

To menene amfanin docker pull? Bisa lafazin takardun:

"Jawo hoto ko wurin ajiya daga wurin yin rajista".

A can kuma mun sami hanyar haɗi zuwa fahimtar hotuna, kwantena, da direbobin ajiya.

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Daga nan za mu iya fahimtar cewa hoton docker wani tsari ne na wasu yadudduka waɗanda ke ɗauke da bayanai game da sabbin canje-canje a cikin hoton, wanda a fili yake abin da muke buƙata. Na gaba mu duba API ɗin rajista.

Yana cewa:

"Hoton" haɗe ne na bayyanuwa ta JSON da fayilolin Layer ɗin mutum ɗaya. Tsarin ja> hoto yana da alaƙa da maido da waɗannan abubuwan biyu."

Don haka mataki na farko bisa ga takardun shine "Janye Bayar da Hoto".

Tabbas, ba za mu harbe shi ba, amma muna buƙatar bayanai daga gare ta. Mai zuwa shine buƙatar misali: GET /v2/{name}/manifests/{reference}

"Sunan da ma'aunin tunani sun gano hoton kuma ana buƙatar su. Ma'anar na iya haɗawa da tag ko narke."

Ana tura ma'ajiyar docker din mu a gida, bari mu yi kokarin aiwatar da bukatar:

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

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

A cikin martani, muna karɓar json wanda a halin yanzu kawai muke sha'awar hanyoyin rayuwa, ko kuma hashes ɗin su. Bayan mun karɓi su, za mu iya bi ta kowane ɗayan kuma mu aiwatar da buƙatun mai zuwa: "GET /v2/{name}/blobs/{digest}"

"Za a ba da izinin shiga Layer da sunan wurin ajiyar amma an gano shi musamman a cikin wurin yin rajista ta hanyar narkewa."

Narke a cikin wannan yanayin shine zanta da muka karɓa.

Gwada

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

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Bari mu ga irin fayil ɗin da muka karɓa a ƙarshe azaman layin rayuwa na farko.

file firstLayer

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

wadanda. dogo ne rumbun adana kwalta, ana kwance su cikin tsari da ya dace za mu samu abin da ke cikin hoton.

Bari mu rubuta ƙaramin rubutun bash domin duk wannan ya zama mai sarrafa kansa

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

Yanzu za mu iya gudanar da shi tare da sigogin da ake so kuma mu sami abubuwan da ke cikin hoton da ake bukata

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

Part 2 - docker turawa

Wannan zai zama ɗan ƙarin rikitarwa.

Bari mu sake farawa da takardun. Don haka muna buƙatar saukar da kowane shugaba, tattara bayanan da suka dace kuma mu zazzage shi ma. Ga alama mai sauƙi.

Bayan nazarin takardun, za mu iya raba tsarin saukewa zuwa matakai da yawa:

  • Tsarin farawa - "POST /v2/{repoName}/blobs/uploads/"
  • Loda layin rayuwa (za mu yi amfani da loda guda ɗaya, watau mu aika kowane layin rayuwa gaba ɗaya) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
    Tsawon Abun ciki: {girman Layer}
    Nau'in abun ciki: aikace-aikace/ rafi-rafi
    Layer Binary Data".
  • Ana loda bayanan - "PUT /v2/{repoName}/bayyanai/{reference}".

Amma takardun sun ɓace mataki ɗaya, ba tare da abin da zai yi aiki ba. Don loda monolithic, da kuma na ɓangarori (chunked), kafin loda layin dogo, dole ne ku yi buƙatun PATCH:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
Tsawon Abun ciki: {girman chunk}
Nau'in abun ciki: aikace-aikace/ rafi-rafi
{Layer Chunk Binary Data}".

In ba haka ba, ba za ku iya wuce matakin farko ba, saboda ... Madadin lambar amsawar da ake tsammanin 202, zaku karɓi 4xx.

Yanzu algorithm yayi kama da:

  • Ƙaddamarwa
  • Faci dogo
  • Ana loda layin hannu
  • Ana loda bayanan
    maki 2 da 3, bi da bi, za a maimaita sau da yawa kamar yadda adadin layin da ake buƙatar lodawa.

Na farko, muna buƙatar kowane hoto. Zan yi amfani da archlinux: latest

docker pull archlinux

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Yanzu bari mu ajiye shi a gida don ƙarin bincike

docker save c24fe13d37b9 -o savedArch

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Cire fakitin rumbun adana bayanai cikin kundin adireshi na yanzu

tar xvf savedArch

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Kamar yadda kuke gani, kowane layin rayuwa yana cikin babban fayil daban. Yanzu bari mu dubi tsarin bayyanuwa da muka samu

cat manifest.json | json_pp

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Ba yawa. Bari mu ga abin da bayyanar da ake bukata don lodi, bisa ga takardun.

Aiwatar da docker ja da docker tura umarni ba tare da abokin ciniki docker ta amfani da buƙatun HTTP ba

Babu shakka, bayanin da ke akwai bai dace da mu ba, don haka za mu yi namu tare da blackjack da ladabi, layin rayuwa da daidaitawa.

Koyaushe za mu sami aƙalla fayil ɗin saiti ɗaya da tsararrun hanyoyin rayuwa. Tsarin tsari 2 (na yanzu a lokacin rubutawa), za a bar mediaType ba canzawa:

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

Bayan ƙirƙirar bayanan asali, kuna buƙatar cika shi da ingantaccen bayanai. Don yin wannan, muna amfani da samfurin json na abin dogo:

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

Za mu ƙara shi zuwa ga bayanin kowane dogo.

Na gaba, muna buƙatar gano girman fayil ɗin saiti kuma mu maye gurbin stubs a cikin bayyananniyar tare da ainihin bayanai

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

Yanzu zaku iya fara aiwatar da zazzagewa kuma ku ceci kanku uuid, wanda yakamata ya bi duk buƙatun na gaba.

Cikakken rubutun yayi kama da haka:

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

za mu iya amfani da shirye-shiryen rubutun:

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

UPS:
Menene muka samu a sakamakon haka?
Da fari dai, ainihin bayanai don bincike, tunda ana gudanar da gwaje-gwaje a cikin blazemeter kuma bayanan akan buƙatun abokin ciniki na docker ba su da cikakken bayani, sabanin buƙatun HTTP masu tsabta.

Na biyu, canjin ya ba mu damar ƙara yawan masu amfani da kayan aikin docker da kusan 150% kuma mu sami matsakaicin lokacin amsa 20-25% cikin sauri. Don saukar da docker, mun sami damar haɓaka adadin masu amfani da 500%, yayin da matsakaicin lokacin amsa ya ragu da kusan 60%.

Gode ​​muku da hankali.

source: www.habr.com

Add a comment