Kubernetes Apply, Replace ja Patch õige võrdlemine

Kubernetesel on mitu ressursside uuendamise varianti: apply, edit, patch ja replace. On tekkinud segadus, mida igaüks neist teeb ja millal neid rakendada. Vaatame lähemalt.

Kubernetes Apply, Replace ja Patch õige võrdlemine

Kui otsige Google'ist fraasi "kubernetes apply vs replace", leiate vastuse StackOverflow'st, mis ei ole õige. Otsides "kubernetes apply vs patch" esimene link on dokumentatsioon kubectl patch, mis ei sisalda võrdlust rakenda ja patch. Selles artiklis käsitletakse erinevaid variante ja ka igaühe korrektset kasutamist.

Kubernetesi ressursi elutsükli jooksul (nt teenus, deployment, ingress jne) on vahel vajalik muuta, lisada või eemaldada teatud omadusi sellest ressursist. Näiteks lisada kommentaar või suurendada või vähendada replika arvu.

Kubernetes CLI

Kui te juba töötate Kubernetes klastritega CLI kaudu, siis olete juba tuttav rakenda ja muuda. Käsk rakenda spetsifikatsiooni lugemisega ressurssi failist ja teeb "upsert" Kubernetes klastrisse, st loob ressursi, kui seda ei ole, ja uuendab, kui see olemas on. Käsk muuda loob ressursi API kaudu, seejärel kirjutab ressursi spetsifikatsiooni kohalikku faili, mida avatakse seejärel tekstiredaktorisse. Pärast faili redigeerimist ja salvestamist, kubectl saab tagasi saadetud muudatused läbi API, mis hoolikalt rakendab need muudatused ressursile.

Kõik ei tea käskudest patch ja asenda. Käsk patch lubab muuta osa ressursi spetsifikatsioonist, edastades ainult muudetud osa käsureas. Käsk asenda töötab samamoodi nagu muuda, kuid kõik tuleb teha käsitsi: tuleb alla laadida ressursi praegune spetsifikatsioon, näiteks kasutades kubectl get -o yaml, redigeerida seda ning seejärel kasutada asenda ressursi uuendamiseks muudetud spetsifikatsiooni alusel. Käsk asenda ei tööta, kui ressursi lugemise ja asendamise vahel on toimunud mingeid muudatusi.

Kubernetes API

Te olete tõenäoliselt tuttav meetoditega CoreV1().Pods().Update(), replaceNamespacedService või patch_namespaced_deployment, kui töötate klastritega läbi Kubernetes API kliendi teeki mõne programmeerimiskeele kasutamisega. Teek käsitleb neid meetodeid HTTP protokolli kaudu, kasutades meetodeid PUT ja PATCH. Sellega update ja asenda kasutatud PUT, ja patch, kui iganes see ei tunduks iseenesestmõistetav, kasutab PATCH.

Oluline on märkida, et kubectl ka töötab klastritega läbi API. Teisisõnu, kubectl– on klientteegi ümbris Go keele jaoks, mis võimaldab oluliselt esitada alamsõnu kompaktses ja loetavas vormis koos API vaikimisi funktsioonidega. Näiteks nagu olete juba märganud, meetod rakenda ei olnud eespool eelmises lõigus mainitud. Praegu (mai 2020, tõlkija märk.) kogu loogika kubectl apply, st mitteeksisteerivate ressursside loomine ja olemasolevate värskendamine, toimub täielikult koodi poolel kubectl. Tehakse pingutusi logika üleviimise rakenda API poolele, kuid see on endiselt beetatesti faasis. Üksikasjalikumalt selgitan allpool.

Vaikimisi Patch

Parim on rakendada patch, kui soovite ressurssi uuendada. Nii töötavad klienditeegid API Kubernetes'i peal, nagu ka kubectl (pole üllatav, sest see on klientteegi ümbris, tõlkija märk.).

Töötage strateegiliselt

Kõik käsud kubectl rakenda, muuda ja patch kasutavad meetodit PATCH HTTP päringutes olemasoleva ressursi uuendamiseks. Kui süveneda käskude elluviimisse, siis kõik kasutavad lähenemist strategic-merge patching ressursside uuendamiseks, kuigi käsk patch võib kasutada ka muid lähenemisviise (rohkem selle kohta allpool). Strateegiline ühinemise patchimine püüab "kõike õigesti teha", ühendades antud spetsifikatsiooni olemasoleva spetsifikatsiooniga. Täpsemalt öeldes, ta püüab liita nii objekte kui ka massiive, mis tähendab, et muudatused on tavaliselt liituvad. Näiteks, käivitades käsk patch uue keskkonnamuutuja lisamisega pod konteineri spetsifikatsiooni, tõukab see selle keskkonnamuutuja olemasolevatele keskkonnamuutujatele lisandumiseks, mitte nende ülekatteks. Selle lähenemisega eemaldamiseks tuleks parameetri väärtus etteantud spetsifikatsioonis sundida nulliks. Millised käskude kubectl uuendamiseks oleks kõige paremad kasutada?

Kui te haldate oma ressursse kubectl apply, on uuendamisel alati parem kasutada kubectl apply, et kubectl võis hallata konfiguratsiooni ja õigesti jälgida taotletud muudatusi rakenduste kaupa. Eelis on alati kasutada rakenda kaasas on see, et see jälgib varem rakendatud spetsifikatsiooni, võimaldades tal teada, millal spetsifikatsiooni omadused ja massiivi elemendid on selgelt eemaldatud. See võimaldab kasutada rakenda omaduste ja massiivi elementide eemaldamiseks, samal ajal kui tavapärane strateegiline ühinemine ei tööta. Käsud muuda ja patch ei uuenda märkmeid, mida kubectl apply rakendab oma muudatuste jälgimiseks, seega on kõik muudatused, mis on jälgitavad ja tehtud Kubernetes API kaudu, kuid mis on tehtud käsudega muuda ja patch, nähtamatud järgnevatele käskudele rakenda, st rakenda ei eemalda neid, isegi kui need ei ilmu sisendspetsifikatsioonis rakenda (Dokumendis on öeldud, et muuda ja patch teevad märkmete uuendusi, mida kasutatakse rakenda, kuid praktikas – ei).

Kui te ei kasuta käsku rakenda, võib kasutada nagu muuda, kui ka patch, valides käsu, mis sobib rohkem tehtava muudatuse jaoks. Omaduste lisamisel ja muutmisel toimivad mõlemad lähenemisviisid umbes samamoodi. Spetsifikatsiooni omaduste või massiivi elementide eemaldamisel muuda käitub see nagu ühekordne jooks rakenda, sealhulgas jälgib, milline oli spetsifikatsioon enne ja pärast redigeerimist, seega saab selgelt eemaldada omadused ja massiivi elemendid ressursist. Omaduse väärtus tuleb selgelt määrata nulliks spetsifikatsioonis, et patch, et seda ressursist eemaldada. Massiivi elemendi eemaldamine strateegilise ühinemise patchimise kaudu on keerulisem, kuna see nõuab ühinemisdirektiivide kasutamist. Vaata allpool muid uuendamisvõimalusi, et valida sobivamaid alternatiive.

Kliendi teegis uuendamise meetodite rakendamiseks, mis käituvad sarnaselt ülaltoodud käskudele, kubectl, tuleks päringutes määrata content-type ühes application/strategic-merge-patch+json. Kui soovite eemaldada omadusi spetsifikatsioonis, peate nende väärtused selgelt määrama nulliks sarnaselt kubectl patch. Kui tuleb eemaldada massiivi elemente, peaksite uuendamise spetsifikatsioonis lisama ühinemisdirektiivid või kasutama muud uuendamise lähenemist.

Teised uuendamise lähenemised

Kubernetes toetab kahte muud uuendamise lähenemist: JSON merge patch ja JSON patch. JSON merge patch lähenemine aktsepteerib osalist Kubernetesi spetsifikatsiooni sisendina ja toetab objektide ühendamist nagu strategic-merge patching lähenemine. Nende vahelise erinevuse tõttu toetab see ainult massiivide asendust, sealhulgas konteinerite massiivi podi spetsifikatsioonis. See tähendab, et JSON merge patchi kasutamisel peate esitama kõikide konteinerite täielikud spetsifikatsioonid, kui muudate mõne konteineri omadust. Seega on see lähenemine kasulik elementide eemaldamiseks massiivist spetsifikatsioonis. Käskude read kasutades saate valida JSON merge patchi, kasutades kubectl patch --type=merge. Kubernetes API-ga töötades tuleks kasutada päringu meetodit PATCH ja seadmise content-type ühes application/merge-patch+json.

JSON-patchi lähenemine, selle asemel, et esitada osaline ressursi spetsifikatsioon, kasutab muudatusi, mida soovite ressursis teha, massiivina, kus iga massiivi element esindab muudatuse kirjelduse, mis tehakse ressursile. See lähenemine on paindlikum ja võimsam viis tehtud muudatuste väljendamiseks, kuid see toob kaasa selle, et tehtud muudatuste loend on eraldi vormingus, mis ei ole Kubernetes, selle asemel, et saata osaline ressursi spetsifikatsioon. kubectl Te saate valida JSON-patchi, kasutades kubectl patch --type=json. Kubernetes API kasutamisel töötab see lähenemine päringu meetodi abil PATCH ja seadmise content-type ühes application/json-patch+json.

Vajad usaldusväärsust – kasutame replace

Mõnel juhul on vajalik veenduda, et ressurssi ei muudeta ressurssi lugemise ja selle värskendamise vahel. Teisisõnu, tasub veenduda, et kõik muudatused jääksid atomaarseteks. Sel juhul tuleks ressursside värskendamiseks kasutada asenda. Näiteks, kui olemas on ConfigMap, mille loendurit uuendavad mitmed allikad, tuleb olla kindel, et kaks allikat ei uuenda loendurit samaaegselt, mis tooks kaasa uuenduse kadumise. Demonstreerimise eesmärgil kujutage ette sündmuste järjestust, kasutades lähenemist patch:

  • A ja B võtavad ressursi praeguse oleku API-st
  • Kumbki neist uuendab kohalikult spetsifikatsiooni, suurendades loendurit ühe võrra ning lisades vastavalt "A" või "B" märkusesse "updated-by"
  • A uuendab ressurssi veidi kiiremini
  • B uuendab ressurssi

Tulemuseks on uuendus A kadumine. Viimane operatsioon patch võidab, loendur suureneb ühe võrra kahe asemel ning "updated-by" märkus lõppeb "B"-ga, mitte sisaldades "A"-t. Vaatame, kuidas see võrreldes eelnimetatuga, kui uuendused toimuvad lähenemisviisi järgi asenda:

  • A ja B võtavad ressursi praeguse oleku API-st
  • Kumbki neist uuendab kohalikult spetsifikatsiooni, suurendades loendurit ühe võrra ning lisades vastavalt "A" või "B" märkusesse "updated-by"
  • A uuendab ressurssi veidi kiiremini
  • B proovib ressurssi uuendada, kuid API tagastab uuenduse tagasilükkamise, kuna ressursi versioon spetsifikatsioonis asenda ei ühti Kuberneteses oleva ressursi praeguse versiooniga, kuna ressursi versioon suurenes A poolt asendamise operatsiooni käigus.

Ülaltoodud juhul peab B ressurssi uuesti hankima, tegema muudatusi uues olekus ja proovima uuesti. asenda. Tulemusena suureneb loendur kahe võrra ning märge "updated-by" sisaldab lõpus "AB".

Eelmainitud näide eeldab, et täidetakse asenda kogu ressursi täielik asendamine. Spetsifikatsioon, mida kasutatakse asenda, peab olema mitte osaline, nagu rakenda, vaid täisteenus, sealhulgas lisamine resourceVersion spetsifikatsiooni metaandmetesse. Kui te ei ole lisanud resourceVersion või antud versioon ei ole praegune, asendamise taotlus lükatakse tagasi. Seega on parim lähenemine asenda – lugeda resurssi, värskendada seda ja kohe asendada. Kasutades kubectl, näeks see välja järgmine:

$ kubectl get deployment my-deployment -o json 
    | jq '.spec.template.spec.containers[0].env[1].value = "new value"' 
    | kubectl replace -f -

Tasub märkida, et järgmised kaks käsku, kui need täidetakse järjestikku, õnnestuvad, kuna deployment.yaml ei sisalda omadust .metadata.resourceVersion

$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml

Tundub, et see on vastuolus ülaltooduga, s.t. "lisamine resourceVersion metandmete spetsifikatsioonis. Kas on vale nii väita? Ei, see ei ole nii, kuna kui kubectl täheldatakse, et te ei ole määranud resourceVersion, loeb ta selle ressursist ja lisab teie määratud spetsifikatsiooni ning alles siis täidab asenda. Kuna see on potentsiaalselt ohtlik, kui tugineda aatomaroodile, töötab kogu see maagia täielikult serveripoolselt kubectl, ei tasu sellele toetuda klientide teeki kasutades, mis töötavad API-ga. Sel juhul peate lugema praegust ressursi spetsifikatsiooni, värskendama seda ja siis täitma PUT päringut.

Ei saa kasutada patch’i – teeme replace

Mõnikord tuleb teha muutusi, mida API ei suuda töödelda. Sellistel juhtudel saab ressurssi sundiselt asendada, kustutades ja luues selle uuesti. See tehakse järgmiselt kubectl replace --force. Käsku käivitades kustutatakse ressursid koheselt ja seejärel luuakse need uuesti pakutud spetsifikatsioonide järgi. API-s ei ole sunnitud asendamise töötlejat ning selle saavutamiseks API kaudu tuleb teha kaks toimingut. Esiteks tuleb kustutada ressurss, määrates sellele gracePeriodSeconds nulliks (0) ja propagationPolicy ennom 'Background', ja seejärel luua see ressurss soovitud spetsifikatsiooniga uuesti.

Oluline: see lähenemine on potentsiaalselt ohtlik ja võib viia määramatute olekuteni.

Kasutage serveripoolset rakendamist.

Nagu eespool mainitud, töötavad Kubernetes'e arendajad loogika rakendamise kallal. rakenda kohast kubectl Kubernetes API-s. Loogika rakenda on saadaval Kubernetes 1.18 kaudu kubectl apply --server-side või API kaudu, kasutades meetodit PATCH koos content-type application/apply-patch+YAML.

Märkus: JSON on samuti õige YAML, seega on võimalik saata spetsifikatsioon JSON-vormingus, isegi kui content-type rakendatakse application/apply-patch+yaml.

Lisaks sellele, et loogika kubectl on kõigile saadaval API kaudu, rakenda serveripoolne jälgib spetsiifikatsioonis väljade eest vastutavaid, võimaldades seega turvalise mitme juurdepääsu selle konfliktivabaks redigeerimiseks. Teisisõnu, kui rakenda serveripoolne laiemalt levib, ilmub universaalne turvaline veebirakenduste haldamise liides erinevate klientide jaoks, näiteks kubectl, Pulumi või Terraform, GitOps ning ka isetegemise skriptide jaoks, mis kasutavad klienditeegi.

Kokkuvõte

Loodetavasti oli see lühike ülevaade erinevatest viisidest klastrite ressursside värskendamiseks teile kasulik. Hea on teada, et vastandused ei ole lihtsalt apply ja replace, kuna saab ressurssi värskendada ka apply, edit, patch või replace abil. Igal lähenemisviisil on oma rakendusala. Aatomaarsete muudatuste jaoks on parem kasutada replace, muul juhul tasub kasutada strategic-merge patchi läbi apply. Loodan, et mõistsite, et ei tasu usaldada Google'i või StackOverflow't otsides "kubernetes apply vs replace". Vähemalt seni, kuni see artikkel ei asenda hetke vastuseid.

Kubernetes Apply, Replace ja Patch õige võrdlemine

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster