HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

اسان وٽ گھاس جا 2 بيگ، 75 ميزيڪلين ٽيبلٽس يونڪس ماحول، ھڪڙو ڊاڪر ريپوزٽري ۽ ڊاڪر ڪلائنٽ کانسواءِ ڊاڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ جو ڪم.

HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

يو ايس ڊي
سوال: هي سڀ ڇا لاءِ آهي؟
جواب: پراڊڪٽ جي لوڊ ٽيسٽنگ (بش استعمال نه ڪندي، اسڪرپٽ تعليمي مقصدن لاءِ مهيا ڪيا ويا آهن). اهو فيصلو ڪيو ويو ته ڊڪر ڪلائنٽ کي استعمال نه ڪيو وڃي اضافي تہن کي گھٽائڻ لاءِ (مناسب حدن اندر) ۽، مطابق، وڌيڪ لوڊ ڪرڻ جو جذبو. نتيجي طور، ڊاکر ڪلائنٽ جي سڀني سسٽم جي دير کي ختم ڪيو ويو. اسان حاصل ڪيو نسبتا صاف لوڊ سڌو سنئون پيداوار تي.
آرٽيڪل استعمال ڪيو ويو GNU ورزن جا اوزار.

پهرين، اچو ته اهو ڄاڻون ته اهي حڪم ڇا ڪندا آهن.

پوء ڇا ڊاکر پل لاء استعمال ڪيو ويو آهي؟ جي مطابق دستاويز:

"رجسٽري مان تصوير يا مخزن کي ڇڪيو".

اتي اسان کي هڪ لنڪ پڻ ملي ٿي سمجھو تصويرون، ڪنٽينرز، ۽ اسٽوريج ڊرائيور.

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 درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

اهي. ريلون ٽار آرڪائيوز آهن، انهن کي مناسب ترتيب ۾ پيڪ ڪرڻ سان اسان تصوير جو مواد حاصل ڪنداسين.

اچو ته هڪ ننڍڙو بش اسڪرپٽ لکون ته جيئن اهو سڀ ڪجهه خودڪار ٿي سگهي

#!/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}
    مواد جي ڊگھائي: {پرت جو سائز}
    مواد جو قسم: ايپليڪيشن/آڪٽيٽ-اسٽريم
    پرت بائنري ڊيٽا".
  • مينيفيسٽ لوڊ ڪري رهيو آهي - "PUT /v2/{repoName}/manifests/{reference}".

پر دستاويز هڪ قدم وڃائي ٿو، جنهن کان سواء ڪجھ به ڪم نه ڪندو. monolithic لوڊ ڪرڻ لاء، گڏوگڏ جزوي (ٽڪڙي) لاء، ريل لوڊ ڪرڻ کان اڳ، توهان کي هڪ PATCH درخواست ڪرڻ گهرجي:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
مواد-ڊگھائي: {ٽڪر جو سائز}
مواد جو قسم: ايپليڪيشن/آڪٽيٽ-اسٽريم
{پرت چنڪ بائنري ڊيٽا}".

ٻي صورت ۾، توهان پهرين نقطي کان اڳتي وڌڻ جي قابل نه هوندا، ڇاڪاڻ ته ... متوقع جوابي ڪوڊ جي بدران 202، توهان وصول ڪندا 4xx.

ھاڻي الورورٿم ڏسڻ ۾ اچي ٿو:

  • شروعات
  • پيچ ريل
  • هٿرادو لوڊ ڪندي
  • منشور لوڊ ڪندي
    پوائنٽس 2 ۽ 3، ترتيب سان، ڪيترائي ڀيرا ورجائي ويندا جيئن لائنن جو تعداد لوڊ ٿيڻ جي ضرورت آھي.

پهرين، اسان کي ڪنهن به تصوير جي ضرورت آهي. مان استعمال ڪندس archlinux:latest

docker pull archlinux

HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

هاڻي اچو ته ان کي مقامي طور تي وڌيڪ تجزيو لاءِ محفوظ ڪريون

docker save c24fe13d37b9 -o savedArch

HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

موجوده ڊاريڪٽري ۾ نتيجو آرڪائيو کي کوليو

tar xvf savedArch

HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

جئين توهان ڏسي سگهو ٿا، هر لائف لائن هڪ الڳ فولڊر ۾ آهي. ھاڻي اچو ته ڏسون ان منشور جي ساخت جو اسان کي مليل آھي

cat manifest.json | json_pp

HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

گهڻو نه. اچو ته ڏسو ته ڇا پڌرو لوڊ ڪرڻ جي ضرورت آهي، مطابق دستاويز.

HTTP درخواستن کي استعمال ڪندي ڊاکر ڪلائنٽ جي بغير ڊڪر پل ۽ ڊڪر پش ڪمانڊ لاڳو ڪرڻ

ظاهر آهي، موجوده منشور اسان لاءِ مناسب نه آهي، تنهنڪري اسان پنهنجو پاڻ ٺاهينداسين بليڪ جيڪ ۽ درٻارن، لائف لائنن ۽ ترتيبن سان.

اسان وٽ هميشه گهٽ ۾ گهٽ هڪ ترتيب واري فائيل ۽ زندگين جي هڪ صف هوندي. اسڪيم ورزن 2 (لکڻ جي وقت تي موجوده)، ميڊيا ٽائپ کي تبديل نه ڪيو ويندو:

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]}"
      },

اسان ان کي هر ريل جي منشور ۾ شامل ڪنداسين.

اڳيون، اسان کي config فائل جي سائيز کي ڳولڻ جي ضرورت آهي ۽ حقيقي ڊيٽا سان منشور ۾ اسٽب کي تبديل ڪرڻ جي ضرورت آهي

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

يو ايس ڊي
نتيجي ۾ اسان کي ڇا مليو؟
پهرين، تجزيي لاءِ حقيقي ڊيٽا، ڇو ته ٽيسٽ هلايا ويندا آهن بليزميٽر ۾ ۽ ڊاڪر ڪلائنٽ جي درخواستن تي ڊيٽا تمام معلوماتي نه آهي، خالص HTTP درخواستن جي برعڪس.

ٻيو، منتقلي اسان کي مجازي استعمال ڪندڙن جو تعداد وڌائڻ جي اجازت ڏني ڊاکر اپلوڊ لاءِ اٽڪل 150٪ ۽ حاصل ڪريو اوسط جوابي وقت 20-25٪ تيز. ڊاڪر ڊائون لوڊ لاءِ، اسان استعمال ڪندڙن جو تعداد 500٪ وڌائڻ ۾ ڪامياب ٿي ويا، جڏهن ته اوسط جوابي وقت اٽڪل 60٪ گھٽجي ويو.

توهان جي ڌيان لاء توهان جي مهرباني.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو