Við vorum með 2 poka af grasi, 75 meskalín spjaldtölvur unix umhverfi, docker geymsla og það verkefni að útfæra docker pull og docker push skipanir án docker biðlara.
UPP:
Spurning: Til hvers er þetta allt?
Svar: Hleðsluprófun á vörunni (EKKI með bash, forskriftirnar eru veittar í fræðsluskyni). Ákveðið var að nota ekki Docker biðlarann til að minnka viðbótarlög (innan skynsamlegra marka) og líkja því eftir hærra álagi. Fyrir vikið voru allar kerfistafir Docker biðlarans fjarlægðar. Við fengum tiltölulega hreint álag beint á vöruna.
Greinin notaði GNU útgáfur af verkfærum.
Fyrst skulum við reikna út hvað þessar skipanir gera.
Svo til hvers er docker pull notað? Samkvæmt
„Taktu mynd eða geymslu úr skrásetningu“.
Þar finnum við líka hlekk á
Héðan getum við skilið að docker mynd er sett af ákveðnum lögum sem innihalda upplýsingar um nýjustu breytingarnar á myndinni, sem er augljóslega það sem við þurfum. Næst skoðum við
Þar segir eftirfarandi:
""Mynd" er sambland af JSON upplýsingaskrá og einstökum lagaskrám. Ferlið við að draga > mynd miðast við að sækja þessa tvo þætti."
Þannig að fyrsta skrefið samkvæmt skjölunum er "Að draga myndbirtingu".
Auðvitað munum við ekki skjóta það, en við þurfum gögnin frá því. Eftirfarandi er dæmi um beiðni: GET /v2/{name}/manifests/{reference}
"Nafnið og tilvísunarfæribreytan auðkenna myndina og eru nauðsynlegar. Tilvísunin getur innihaldið merki eða samantekt."
Docker geymslan okkar er sett upp á staðnum, við skulum reyna að framkvæma beiðnina:
curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/manifests/1.1.1" -H "header_if_needed"
Til að bregðast við fáum við json frá sem við höfum sem stendur aðeins áhuga á líflínunum, eða öllu heldur kjötkássa þeirra. Eftir að hafa fengið þær, getum við farið í gegnum hvern og einn og framkvæmt eftirfarandi beiðni: "GET /v2/{name}/blobs/{digest}"
„Aðgangur að lagi verður lokaður með nafni geymslunnar en er auðkenndur einstaklega í skránni með samdrætti.
samantekt í þessu tilfelli er kjötkássa sem við fengum.
Reynir
curl -s -X GET "http://localhost:8081/link/to/docker/registry/v2/centos-11-10/blobs/sha256:f972d139738dfcd1519fd2461815651336ee25a8b54c358834c50af094bb262f" -H "header_if_needed" --output firstLayer
Við skulum sjá hvers konar skrá við fengum loksins sem fyrsta björgunarlínuna.
file firstLayer
þeim. teinar eru tjöruskjalasafn, við að pakka þeim upp í viðeigandi röð munum við fá innihald myndarinnar.
Við skulum skrifa lítið bash forskrift svo hægt sé að gera þetta allt sjálfvirkt
#!/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
Nú getum við keyrt það með viðeigandi breytum og fengið innihald nauðsynlegrar myndar
./script.sh dirName “http://localhost:8081/link/to/docker/registry” myAwesomeImage 1.0
Part 2 - Docker push
Þetta verður aðeins flóknara.
Byrjum aftur með
Eftir að hafa kynnt okkur skjölin getum við skipt niðurhalsferlinu í nokkur skref:
- Frumstilling ferli - "POST /v2/{repoName}/blobs/uploads/"
- Að hlaða upp björgunarlínu (við munum nota einhlíta upphleðslu, þ.e. við sendum hverja björgunarlínu í heild sinni) - "PUT /v2/{repoName}/blobs/uploads/{uuid}?digest={digest}
Efnislengd: {stærð lags}
Efnistegund: forrit/oktett-straumur
Lag tvöfaldur gögn". - Hleður upplýsingaskránni - "PUT /v2/{repoName}/manifests/{reference}".
En skjölin missa af einu skrefi, án þess mun ekkert virka. Fyrir einhleypta hleðslu, sem og fyrir hluta (klumpa), áður en járnbrautin er hlaðin, verður þú að framkvæma PATCH beiðni:
"PATCH /v2/{repoName}/blobs/uploads/{uuid}
Innihaldslengd: {stærð klumpur}
Efnistegund: forrit/oktett-straumur
{Layer Chunk Binary Data}".
Annars muntu ekki geta farið lengra en fyrsta stigið, vegna þess að... Í stað væntanlegs svarkóða 202 færðu 4xx.
Nú lítur reikniritið svona út:
- Frumstilling
- Patch rail
- Að hlaða handrið
- Hleður upplýsingaskrá
Liðir 2 og 3, í sömu röð, verða endurteknir eins oft og þarf að hlaða fjölda lína.
Í fyrsta lagi þurfum við hvaða mynd sem er. Ég mun nota archlinux:nýjasta
docker pull archlinux
Nú skulum við vista það á staðnum til frekari greiningar
docker save c24fe13d37b9 -o savedArch
Pakkaðu skjalasafninu sem myndast í núverandi möppu
tar xvf savedArch
Eins og þú sérð er hver líflína í sérstakri möppu. Nú skulum við líta á uppbyggingu upplýsingaskrárinnar sem við fengum
cat manifest.json | json_pp
Ekki mikið. Við skulum sjá hvaða farmskrá þarf til að hlaða, skv
Augljóslega hentar núverandi stefnuskrá okkur ekki, svo við munum búa til okkar eigin með blackjack og kurteisi, líflínum og stillingum.
Við munum alltaf hafa að minnsta kosti eina stillingarskrá og fjölda líflína. Scheme útgáfa 2 (núverandi þegar þetta er skrifað), mediaType verður óbreytt:
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
Eftir að grunnskráin hefur verið búin til þarftu að fylla hana með gildum gögnum. Til að gera þetta notum við json sniðmát járnbrautarhlutarins:
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": ${layersSizes[$i]},
"digest": "sha256:${layersNames[$i]}"
},
Við munum bæta því við upplýsingaskrána fyrir hverja braut.
Næst þurfum við að finna út stærð stillingaskrárinnar og skipta út stubbunum í upplýsingaskránni fyrir raunveruleg gögn
sed -i "s/config_size/$configSize/g; s/config_hash/$configName/g" $manifestFile
Nú geturðu hafið niðurhalsferlið og vistað þér uuid, sem ætti að fylgja öllum síðari beiðnum.
Allt handritið lítur einhvern veginn svona út:
#!/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
við getum notað tilbúið handrit:
./uploadImage.sh "~/path/to/saved/image" "http://localhost:8081/link/to/docker/registry" myRepoName 1.0
UPP:
Hvað fengum við í kjölfarið?
Í fyrsta lagi raunveruleg gögn til greiningar, þar sem prófin eru keyrð í blazemeter og gögnin um beiðnir um tengilið viðskiptavina eru ekki mjög upplýsandi, ólíkt hreinum HTTP beiðnum.
Í öðru lagi, umskiptin leyfðu okkur að fjölga sýndarnotendum fyrir upphleðslu bryggju um 150% og fá meðalsvarstíma 20-25% hraðar. Fyrir docker niðurhal tókst okkur að fjölga notendum um 500%, en meðalviðbragðstími minnkaði um um 60%.
Þakka þér fyrir athygli þína.
Heimild: www.habr.com