Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Мо 2 халта алаф, муҳити unix 75 планшети мескалинӣ, анбори докер ва вазифаи амалисозии фармонҳои докер кашидан ва докерро бидуни муштарии докер доштем.

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

ИПҶ - ИТТИҲОДИ ПОЧТАИ ҶАҲОНИ:
Савол: Ин ҳама барои чӣ аст?
Ҷавоб: Санҷиши боркунии маҳсулот (НЕТАВОНЕД bash, скриптҳо барои мақсадҳои таълимӣ дода шудаанд). Қарор дода шуд, ки муштарии докерро барои кам кардани қабатҳои иловагӣ (дар доираи маҳдудиятҳои оқилона) истифода набаред ва мувофиқан тақлид кардани сарбории баландтар. Дар натиҷа, ҳама таъхирҳои системаи муштарии Docker хориҷ карда шуданд. Мо бевосита ба махсулот бори нисбатан тоза гирифтем.
Дар мақола версияҳои GNU асбобҳо истифода шудааст.

Аввалан, биёед бифаҳмем, ки ин фармонҳо чӣ кор мекунанд.

Пас, docker pull барои чӣ истифода мешавад? Бино бар хуччатхо:

"Тасвир ё анбори реестрро кашед".

Дар он ҷо мо инчунин пайвандеро пайдо мекунем тасвирҳо, контейнерҳо ва драйверҳои анборро дарк кунед.

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Аз ин ҷо мо метавонем фаҳмем, ки тасвири докер маҷмӯи қабатҳои муайянест, ки дорои маълумот дар бораи тағйироти охирини тасвир мебошад, ки баръало он чизест, ки ба мо лозим аст. Минбаъд мо дида мебароем API реестр.

Дар он гуфта мешавад:

"Тасвир" маҷмӯи файлҳои манифести 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"

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Дар посух, мо 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

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Биёед бубинем, ки чӣ гуна файлро мо дар ниҳоят ҳамчун хатти аввалини ҳаёт гирифтем.

file firstLayer

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

ки. релсҳо архиви қатрон мебошанд, онҳоро бо тартиби мувофиқ кушода, мо мундариҷаи тасвирро мегирем.

Биёед як скрипти хурди bash нависем, то ҳамаи ин автоматӣ карда шавад

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

Қисми 2 - такони докер

Ин каме мураккабтар хоҳад шуд.

Биёед аз нав оғоз кунем хуччатхо. Пас, мо бояд ҳар як роҳбарро зеркашӣ кунем, манифести мувофиқро ҷамъ кунем ва онро низ зеркашӣ кунем. Ин оддӣ ба назар мерасад.

Пас аз омӯзиши ҳуҷҷатҳо, мо метавонем раванди зеркашӣро ба якчанд марҳила тақсим кунем:

  • Оғозсозии раванд - "POST /v2/{repoName}/blobs/uploads/"
  • Боркунии хати ҳаёт (мо боркунии монолитиро истифода хоҳем кард, яъне мо ҳар як хати ҳаётро пурра мефиристем) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
    Content-Length: {андозаи қабат}
    Content-Type: барнома/октет-стрем
    Қабати маълумоти дуӣ».
  • Боркунии манифест - "PUT /v2/{repoName}/manifests/{reference}".

Аммо ҳуҷҷат як қадамро аз даст медиҳад, ки бе он чизе кор намекунад. Барои боркунии монолитӣ, инчунин барои қисман (порча) пеш аз бор кардани роҳи оҳан, шумо бояд дархости PATCH-ро иҷро кунед:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
Дарозии мундариҷа: {андозаи порча}
Content-Type: барнома/октет-стрем
{Маълумоти дуии қабати Chunk}".

Дар акси ҳол, шумо наметавонед аз нуқтаи аввал берун равед, зеро... Ба ҷои рамзи ҷавоби 202, шумо 4xx мегиред.

Акнун алгоритм чунин менамояд:

  • Ибтидоӣ
  • Роҳи оҳан
  • Бор кардани дастак
  • Манифест бор карда мешавад
    Нуқтаҳои 2 ва 3, мутаносибан, ҳамон қадар такрор карда мешаванд, ки шумораи сатрҳо бояд бор карда шаванд.

Аввалан, ба мо ягон тасвир лозим аст. Ман archlinux: навтаринро истифода хоҳам кард

docker pull archlinux

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Акнун биёед онро барои таҳлили минбаъда захира кунем

docker save c24fe13d37b9 -o savedArch

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Архиви ҳосилшударо ба феҳристи ҷорӣ кушоед

tar xvf savedArch

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Тавре ки шумо мебинед, ҳар як хатти ҳаёт дар папкаи алоҳида ҷойгир аст. Акнун биёед ба сохтори манифести гирифтаамон назар андозем

cat manifest.json | json_pp

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Бисёр не. Биёед бубинем, ки чӣ гуна манифест барои бор кардан лозим аст, мувофиқи хуччатхо.

Татбиқи фармонҳои докер кашидан ва докер пуш бидуни муштарии докер бо истифода аз дархостҳои HTTP

Аён аст, ки манифести мавҷуда ба мо мувофиқат намекунад, аз ин рӯ мо худамонро бо blackjack ва куртизанҳо, хатҳои ҳаёт ва конфигуратсияҳо месозем.

Мо ҳамеша ҳадди аққал як файли конфигуратсия ва як қатор хатҳои ҳаёт хоҳем дошт. Нақшаи версияи 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

ИПҶ - ИТТИҲОДИ ПОЧТАИ ҶАҲОНИ:
Дар натиҷа мо чӣ ба даст овардем?
Аввалан, маълумоти воқеӣ барои таҳлил, зеро санҷишҳо дар blazemeter гузаронида мешаванд ва маълумот дар бораи дархостҳои муштарии docker, бар хилофи дархостҳои холиси HTTP, чандон иттилоотӣ нестанд.

Дуюм, гузариш ба мо имкон дод, ки шумораи корбарони виртуалиро барои боркунии докер тақрибан 150% зиёд кунем ва вақти вокуниши миёнаро 20-25% тезтар ба даст орем. Барои зеркашии docker, мо тавонистем шумораи корбаронро 500% зиёд кунем, дар ҳоле ки вақти миёнаи посух тақрибан 60% кам шуд.

Ташаккур ба диққататон.

Манбаъ: will.com

Илова Эзоҳ