HTTP கோரிக்கைகளைப் பயன்படுத்தி டோக்கர் கிளையன்ட் இல்லாமல் டோக்கர் புல் மற்றும் டோக்கர் புஷ் கட்டளைகளை செயல்படுத்துதல்

எங்களிடம் 2 பைகள் புல், 75 மெஸ்கலைன் மாத்திரைகள் யூனிக்ஸ் சூழல், ஒரு டாக்கர் களஞ்சியம் மற்றும் டாக்கர் கிளையன்ட் இல்லாமல் டோக்கர் புல் மற்றும் டோக்கர் புஷ் கட்டளைகளை செயல்படுத்தும் பணி இருந்தது.

HTTP கோரிக்கைகளைப் பயன்படுத்தி டோக்கர் கிளையன்ட் இல்லாமல் டோக்கர் புல் மற்றும் டோக்கர் புஷ் கட்டளைகளை செயல்படுத்துதல்

யு பி எஸ்:
கேள்வி: இதெல்லாம் எதற்காக?
பதில்: தயாரிப்பின் சுமை சோதனை (பாஷைப் பயன்படுத்துவதில்லை, ஸ்கிரிப்டுகள் கல்வி நோக்கங்களுக்காக வழங்கப்படுகின்றன). கூடுதல் அடுக்குகளைக் குறைக்க (நியாயமான வரம்புகளுக்குள்) டோக்கர் கிளையண்டைப் பயன்படுத்த வேண்டாம் என்று முடிவு செய்யப்பட்டது, அதன்படி, அதிக சுமைகளைப் பின்பற்றவும். இதன் விளைவாக, டோக்கர் கிளையண்டின் அனைத்து கணினி தாமதங்களும் அகற்றப்பட்டன. தயாரிப்பில் நேரடியாக ஒப்பீட்டளவில் சுத்தமான சுமையைப் பெற்றோம்.
கட்டுரை குனு பதிப்பு கருவிகளைப் பயன்படுத்தியது.

முதலில், இந்த கட்டளைகள் என்ன செய்கின்றன என்பதைக் கண்டுபிடிப்போம்.

டாக்கர் புல் எதற்காகப் பயன்படுத்தப்படுகிறது? படி ஆவணங்கள்:

"ஒரு பதிவேட்டில் இருந்து ஒரு படத்தை அல்லது ஒரு களஞ்சியத்தை இழுக்கவும்".

அதற்கான இணைப்பையும் அங்கே காணலாம் படங்கள், கொள்கலன்கள் மற்றும் சேமிப்பக இயக்கிகள் ஆகியவற்றைப் புரிந்து கொள்ளுங்கள்.

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

"ஒரு அடுக்குக்கான அணுகல் களஞ்சியத்தின் பெயரால் இணைக்கப்படும், ஆனால் டைஜெஸ்ட் மூலம் பதிவேட்டில் தனித்துவமாக அடையாளம் காணப்படும்."

இந்த விஷயத்தில் 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}".

ஆனால் ஆவணங்கள் ஒரு படியை இழக்கின்றன, அது இல்லாமல் எதுவும் இயங்காது. மோனோலிதிக் ஏற்றுவதற்கும், பகுதியளவு (துண்டுகள்) ரெயிலை ஏற்றுவதற்கு முன், நீங்கள் ஒரு பேட்ச் கோரிக்கையைச் செய்ய வேண்டும்:

"PATCH /v2/{repoName}/blobs/uploads/{uuid}
உள்ளடக்க நீளம்: {துண்டின் அளவு}
உள்ளடக்க வகை: பயன்பாடு/ஆக்டெட் ஸ்ட்ரீம்
{Layer Chunk பைனரி தரவு}".

இல்லையெனில், நீங்கள் முதல் புள்ளியைத் தாண்டி செல்ல முடியாது, ஏனென்றால்... எதிர்பார்க்கப்படும் மறுமொழிக் குறியீடு 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 கோரிக்கைகளைப் பயன்படுத்தி டோக்கர் கிளையன்ட் இல்லாமல் டோக்கர் புல் மற்றும் டோக்கர் புஷ் கட்டளைகளை செயல்படுத்துதல்

வெளிப்படையாக, தற்போதுள்ள மேனிஃபெஸ்டோ எங்களுக்குப் பொருந்தாது, எனவே பிளாக் ஜாக் மற்றும் வேசிகள், லைஃப்லைன்கள் மற்றும் கட்டமைப்புகளுடன் நாங்கள் சொந்தமாக உருவாக்குவோம்.

எங்களிடம் எப்போதும் குறைந்தது ஒரு config file மற்றும் லைஃப்லைன்களின் வரிசை இருக்கும். திட்ட பதிப்பு 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

கருத்தைச் சேர்