Krahasimi i saktë i Kubernetes Apply, Replace dhe Patch

Për Kubernetes ekzistojnë disa mënyra për të përditësuar burimet: apply, edit, patch dhe replace. Ka konfuzion rreth asaj se çfarë bën secili dhe kur duhet t'i përdorim ato. Le të sqarojmë.

Krahasimi i saktë i Kubernetes Apply, Replace dhe Patch

NĂ«se kĂ«rkoni nĂ« Google fraza "kubernetes apply vs replace", do tĂ« gjeni njĂ« pĂ«rgjigje nĂ« StackOverflow, e cila nuk Ă«shtĂ« e saktĂ«. Nga kĂ«rkimi "kubernetes apply vs patch" lidhja e parĂ« — dokumentacioni mbi kubectl patch, i cili nuk pĂ«rfshin njĂ« krahasim aplikoni dhe patch. NĂ« kĂ«tĂ« artikull do tĂ« shqyrtohen mĂ«nyra tĂ« ndryshme, si dhe pĂ«rdorimi i saktĂ« i secilĂ«s prej tyre.

Gjatë ciklit të jetës së një burimi Kubernetes (shërbimi, deployment, ingress etj.) ndonjëherë duhet të ndryshoni, shtoni ose fshini disa karakteristika të këtij burimi. Për shembull, të shtoni një shënim, të rrisni ose zvogëloni numrin e replikave.

Kubernetes CLI

Nëse tashmë po punoni me klasterë Kubernetes nëpërmjet CLI, atëherë jeni njohur me aplikoni dhe edit. Komanda aplikoni lexon specifikimin e burimit nga një skedër dhe bën "upsert" në klasterin Kubernetes, pra krijon burimin nëse nuk ekziston dhe e përditëson nëse ai ekziston. Komanda edit lexon burimin përmes API, pastaj shkruan specifikimin e burimit në një skedë lokale, e cila pastaj hapet në një redaktor teksti. Pasi ta redaktoni dhe ta ruani skedën, kubectl do të dërgojë ndryshimet e bëra përsëri përmes API, i cili me kujdes do t'i zbatojë këto ndryshime në burim.

Nuk të gjithë e dinë komandën patch dhe ndërrim. Komanda patch lejon të ndryshoni një pjesë të specifikimit të burimit, duke ofruar vetëm pjesën e ndryshuar në komandën e linjës. Komanda ndërrim punon ngjashëm me edit, por gjithçka duhet bërë manualisht: duhet të shkarkoni versionin aktual të specifikimit të burimit, për shembull duke përdorur kubectl get -o yaml, ta redaktoni atë, pastaj të përdorni ndërrim për të përditësuar burimin sipas specifikimit të ndryshuar. Komanda ndërrim nuk do të funksionojë nëse gjatë leximit dhe zëvendësimit të burimit janë ndodhur ndonjëherë ndryshime.

Kubernetes API

Padyshim që jeni njohur me metodat CoreV1().Pods().Update(), replaceNamespacedService ose patch_namespaced_deployment, nëse punoni me klasterë përmes bibliotekës klient për API Kubernetes duke përdorur një gjuhë programimi. Biblioteka trajton këto metoda përmes kërkesave në protokollin HTTP, duke përdorur metodat PUT dhe PATCH. Ndërkohë, përditësim dhe ndërrim përdorin PUT, ndërsa patch, pavarësisht se sa e thjeshtë të duket, përdor PATCH.

Duhet theksuar se kubectl po ashtu punon me klasterĂ« pĂ«rmes API. MĂ« nĂ« fund, kubectl– Ă«shtĂ« njĂ« mbĂ«shtetje mbi bibliotekĂ«n e klientit pĂ«r gjuhĂ«n Go, qĂ« ofron nĂ« masĂ« tĂ« madhe mundĂ«sinĂ« pĂ«r tĂ« siguruar nĂ«nkomanda nĂ« njĂ« mĂ«nyrĂ« mĂ« tĂ« kompaktĂ« dhe mĂ« tĂ« lexueshme pĂ«rveç funksionaliteteve standarde tĂ« API. PĂ«r shembull, siç e keni vĂ«nĂ« re, metoda aplikoni nuk u pĂ«rmend mĂ« sipĂ«r nĂ« paragrafin e kaluar. Aktualisht (maj 2020, shĂ«n. e pĂ«rkthyesit) gjithĂ« logjika kubectl apply, dmth krijimi i burimeve qĂ« nuk ekzistojnĂ« dhe azhurnimi i atyre ekzistuese, funksionon plotĂ«sisht nĂ« anĂ«n e kodit kubectl. Po bĂ«hen pĂ«rpjekje pĂ«r tĂ« zhvendosur logjikĂ«n aplikoni nĂ« anĂ«n e API, por kjo Ă«shtĂ« ende nĂ« fazĂ«n e beta-testimit. Do tĂ« shpjegoj mĂ« poshtĂ«.

Patch në parazgjedhje

Më mirë është të aplikohet patch, nëse dëshironi të azhurnoni burimin. Kështu funksionojnë si bibliotekat klienti mbi API e Kubernetes, ashtu si kubectl (nuk është befasi, për sa kohë që është mbështetje e bibliotekës klient) shën. e përkthyesit).

TĂ« punosh strategjikisht

Të gjitha komandat kubectl aplikoni, edit dhe patch përdorin metodën PATCH në kërkesat HTTP për azhurnimin e burimit ekzistues. Nëse shikoni më në detaje realizimin e komandeve, të gjitha përdorin qasjen strategic-merge patching për të azhurnuar burimet, megjithatë komanda patch mund të përdorë edhe qasje të tjera (më shumë rreth kësaj më poshtë). Qasja strategic-merge patching përpiqet të "bëjë gjithçka siç duhet" gjatë kombinimit të specifikimit të ofruar me specifikimin ekzistues. Më konkretisht, ajo përpiqet të kombinojë si objekte ashtu edhe array, që do të thotë se ndryshimet në përgjithësi janë aditive. Për shembull, ekzekutimi i komandas patch me një variabël të re ambienti në specifikimin e kontejnerit pod, bën që ky variabël ambienti të shtohet në variablat ekzistues, e jo të zëvendësojë ato. Për të fshirë përmes këtij metodi duhet të vendosni forcërisht vlerën e parametrave në null në specifikimin e ofruar. Cilat janë komandat kubectl për azhurnim që është më mirë të përdoren?

Nëse po krijoni dhe menaxhoni burimet tuaja përmes kubectl apply, gjatë azhurnimit gjithmonë është më mirë të përdorni kubectl apply, që kubectl mund të menaxhojë konfigurimin dhe të ndjekë saktësisht ndryshimet e kërkuara nga aplikimi në aplikim. Avantazhi i përdorimit të vazhdueshëm të aplikoni është se ai ndjek specifikimin e aplikuar më parë, duke e lejuar të dijë kur pronat e specifikimit dhe elementët e array-së hiqen në mënyrë të qartë. Kjo lejon përdorimin aplikoni për të hequr pronat dhe elementet e një matrice, ndryshe nga një bashkim strategjik normal që nuk do të funksionojë. Komandat edit dhe patch nuk azhurnojnë shënimet që kubectl apply aplikohet për të ndjekur ndryshimet e tij, prandaj çdo ndryshim që ndjeket dhe bëhet përmes API Kubernetes, por që është bërë përmes komandave edit dhe patch, nuk është i dukshëm për komandat në vazhdim aplikoni, që do të thotë aplikoni nuk i heq ato, madje edhe nëse ato nuk shfaqen në specifikimin e hyrjes për aplikoni (Në dokumentacion thotë se edit dhe patch bëjnë azhurnime shënimesh që janë përdorur aplikoni, por në praktikë - jo).

Nëse nuk po përdorni komandën aplikoni, mund të përdoret si edit, ashtu edhe patch, duke zgjedhur komandën që përshtatet më mirë me ndryshimin që bëhet. Kur shtoni dhe ndryshoni pronat e specifikimit, të dy qasjet janë afërsisht të ngjashme. Kur hiqen pronat e specifikimit ose elementet e matrice edit vepron si një ekzekutiv njëherësh aplikoni, përfshirë ndjekjen e çfarë ka qenë specifikimi përpara dhe pas redaktimit, prandaj mund të hiqen qartë pronat dhe elementet e matrice nga burimi. Duhet t'i vendosni qartë vlerat e pronave në null në specifikimin për patch, për ta hequr nga burimi. Heqja e një elementi të matrice duke përdorur patching strategic-merge është më e komplikuar, pasi kërkon përdorimin e direktivave të bashkimit. Shikoni qasje të tjera për azhurnime më poshtë për të zgjedhur alternativa më të pranueshme.

Për të implementuar në bibliotekën e klientit metodat e azhurnimit që veprojnë ashtu si komandat e mësipërme kubectl, duhet të vendosni në kërkesa content-type në application/strategic-merge-patch+json. Nëse dëshironi të hiqni pronat në specifikim, duhet t'i vendosni qartë vlerat e tyre në null ashtu si kubectl patch. Nëse duhet të hiqni elemente të matrice, duhet të përfshini direktivat e bashkimit në specifikimin e azhurnimit ose të përdorni një qasje tjetër për azhurnime.

Qasje të tjera për azhurnime

Në Kubernetes mbështeten dy qasje të tjera për azhurnime: JSON merge patch dhe JSON patchPraktika JSON merge patch pranon një specifikim të pjesshëm Kubernetes si hyrje dhe mbështet bashkimin e objekteve, si qasja e strategjisë së bashkimit. Dallimi midis tyre është se ai mbështet vetëm zëvendësimin e arrave, duke përfshirë arrën e kontejnerëve në specifikimin e pod. Kjo do të thotë se kur përdorni JSON merge patch, ju nevojitet të ofroni specifikime të plota për të gjithë kontejnerët në rast se ndonjë pronë e ndonjë kontejneri ndryshohet. Kështu, ky qasje është e dobishme për të hequr elementë nga një array në specifikim. Në komandën e linjës mund të zgjidhni JSON merge patch, duke përdorur kubectl patch --type=merge. Gjatë punës me API Kubernetes, duhet të përdorni metodën e kërkesës PATCH dhe caktimi content-type në application/merge-patch+json.

Praktika JSON patch në vend të ofrimit të një specifikimi të pjesshëm të burimit, përdor ofrimin e ndryshimeve që dëshironi të bëni në burim si një array, ku secili element i array-it paraqet përshkrimin e ndryshimit që po bëhet në burim. Ky qasje është një mënyrë më fleksibile dhe të fuqishme për të shprehur ndryshimet, por ndarja e listës së ndryshimeve shkon në një format të veçantë, jo Kubernetes, në vend të dërgimit të një specifikimi të pjesshëm të burimit. Në kubectl mund të zgjidhni JSON patch, duke përdorur kubectl patch --type=json. Kur përdorni API Kubernetes, ky qasje funksionon duke përdorur metodën e kërkesës PATCH dhe caktimi content-type në application/json-patch+json.

Keni nevojë për siguri - përdorni replace

Në disa raste, nevojitet siguri që burimi të mos ndryshohet midis kohës së leximit të burimit dhe përditësimit të tij. Në të tjerat fjalë, duhet të jeni të sigurt se të gjitha ndryshimet do të jenë atomare. Në këtë rast, për të përditësuar burimet, duhet të përdorni ndërrim. Për shembull, nëse ka një ConfigMap me një numërator që përditësohet nga burime të shumta, duhet të siguroheni që dy burime të mos përditësojnë numëratorin njëkohësisht, që do të çonte në humbjen e përditësimit. Për të demonstruar, imagjinoni një sekuencë ngjarjesh duke përdorur qasjen patch:

  • A dhe B marrin gjendjen aktuale tĂ« burimit nga API
  • Secili prej tyre lokalisht pĂ«rditĂ«son specifikimin, duke rritur numĂ«ratorin me njĂ«si dhe duke shtuar "A" ose "B" pĂ«rkatĂ«sisht nĂ« shĂ«nimin "updated-by"
  • A ndoshta pĂ«rditĂ«son burimin pak mĂ« shpejt
  • B pĂ«rditĂ«son burimin

Si pasqyra e përditësimit A është humbur. Operacioni më i fundit patch fiton, numri rritet me një në vend të dyve, dhe vlera e shënimit "updated-by" përfundon me "B" dhe nuk përmban "A". Le të krahasojmë këtë me atë që ndodh kur përditësimet kryhen duke përdorur qasjen ndërrim:

  • A dhe B marrin gjendjen aktuale tĂ« burimit nga API
  • Secili prej tyre lokalisht pĂ«rditĂ«son specifikimin, duke rritur numĂ«ratorin me njĂ«si dhe duke shtuar "A" ose "B" pĂ«rkatĂ«sisht nĂ« shĂ«nimin "updated-by"
  • A ndoshta pĂ«rditĂ«son burimin pak mĂ« shpejt
  • B pĂ«rpiqet tĂ« pĂ«rditĂ«sojĂ« burimin, por pĂ«rditĂ«simi Ă«shtĂ« refuzuar nga API-ja, sepse versioni i burimit nĂ« specifikim ndĂ«rrim nuk pĂ«rputhet me versionin aktual tĂ« burimit nĂ« Kubernetes, pasi versioni i burimit Ă«shtĂ« rritur gjatĂ« ekzekutimit tĂ« operacionit tĂ« zĂ«vendĂ«simit nga A.

Në rastin e mësipërm, B do të ketë nevojë të nxjerrë përsëri burimin, të bëjë ndryshime në gjendjen e re dhe të përpiqet përsëri ta bëjë ndërrim. Si rezultat, numri do të rritet me dy, dhe shënimi "updated-by" do të përmbajë "AB" në fund.

Shembulli i mësipërm nënkupton se gjatë ekzekutimit ndërrim bëhet një zëvendësim i plotë i të gjithë burimit. Specifikimi që përdoret për ndërrim, duhet të jetë jo pjesor, ose për pjesë si në aplikoni, por i plotë, duke përfshirë shtimin e resourceVersion në metadatën e specifikimit. Nëse nuk e keni përfshirë resourceVersion ose versioni që keni dhënë nuk është aktual, zëvendësimi do të refuzohet. Pra, qasja më e mirë për t'u përdorur ndërrim është të lexoni burimin, ta përditësoni dhe ta zëvendësoni menjëherë. Duke përdorur kubectl, kjo mund të duket kështu:

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

Me këtë vërejtje, dy komandat e mëposhtme, të ekzekutuara radhazi, do të ekzekutohen me sukses, sepse deployment.yaml nuk përmban pronën .metadata.resourceVersion

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

Kjo duket se është në kundërshtim me atë që u tha më sipër, pra "shtimi resourceVersion në metadatën e specifikimit". A është gabim të argumentosh kështu? Jo, nuk është, sepse nëse kubectl vëren se nuk ke specifikuar resourceVersion, ai do ta lexojë nga burimi dhe do ta shtojë në specifikimin që ke dhënë dhe pastaj do të kryejë ndërrim. Duke qenë se kjo është potencialisht e rrezikshme, nëse mbështetesh në atomaritet, magia funksionon plotësisht nga kubectl, nuk është e rekomandueshme të mbështetesh në të kur përdor bibliotekat e klientit që veprojnë me API. Në këtë rast, do të kesh nevojë të lexosh specifikimin aktual të burimit, ta përditësosh dhe pastaj të kryesh PUT kërkesën.

Nuk mund tĂ« bĂ«j patch – bĂ«j zĂ«vendĂ«sim

NdonjĂ«herĂ« Ă«shtĂ« e nevojshme tĂ« bĂ«ni disa ndryshime qĂ« nuk mund tĂ« pĂ«rpunohen nga API. NĂ« kĂ«to raste, mund tĂ« zĂ«vendĂ«soni me forcĂ« burimin duke hequr dhe krijuar pĂ«rsĂ«ri atĂ«. Kjo bĂ«het pĂ«rmes kubectl replace --force. Ekzekutimi i komandĂ«s menjĂ«herĂ« heq burimet dhe pastaj i rikrijon ato me specifikimin e dhĂ«nĂ«. NĂ« API nuk ka njĂ« pĂ«rpunues "zĂ«vendĂ«so me forcĂ«", dhe pĂ«r ta bĂ«rĂ« kĂ«tĂ« pĂ«rmes API, duhet tĂ« kryhen dy operacione. SĂ« pari, duhet tĂ« hiqni burimin, duke caktuar pĂ«r tĂ« gracePeriodSeconds nĂ« zero (0) dhe propagationPolicy nĂ« “Background”, dhe pastaj ta krijoni pĂ«rsĂ«ri kĂ«tĂ« burim me specifikimin e dĂ«shiruar.

Kujdes: ky qasje është potencialisht e rrezikshme, dhe mund të çojë në një gjendje të paqartë

Apliko në anën e serverit

Siç e përmenda më lart, zhvilluesit e Kubernetes po punojnë për të realizuar logjikën aplikoni nga kubectl në API-në e Kubernetes. Logjika aplikoni është e disponueshme në Kubernetes 1.18 përmes kubectl apply --server-side ose përmes API-së, duke përdorur metodën PATCH me content-type application/apply-patch+YAML.

Shënim: JSON gjithashtu është një YAML i saktë, ndaj mund të dërgohet specifikimi në formën e JSON, edhe nëse content-type do të application/apply-patch+yaml.

Për më tepër, logjika kubectl bëhet e disponueshme për të gjithë përmes API-së, aplikoni në anën e serverit monitoron përgjegjësit për fushat në specifikim, duke lejuar kështu një qasje të sigurt për redaktime pa konflikte. Me fjalë të tjera, nëse aplikoni në anën e serverit përhapet më gjerësisht, do të krijohet një ndërfaqe e sigurt për menaxhimin e burimeve për klientë të ndryshëm, për shembull, kubectl, Pulumi ose Terraform, GitOps, si dhe skenarë të shkruar vetë që përdorin bibliotekat klient.

Përfundime

Shpresoj se kjo pĂ«rmbledhje e shkurtĂ«r e mĂ«nyrave tĂ« ndryshme pĂ«r tĂ« pĂ«rditĂ«suar burimet nĂ« klastera ka qenĂ« e dobishme pĂ«r ju. ËshtĂ« e dobishme tĂ« dini se kundĂ«rshtitĂ« nuk janĂ« vetĂ«m apliko pĂ«rballĂ« zĂ«vendĂ«simit, sepse mund tĂ« pĂ«rditĂ«soni burimin me apliko, redakto, patch ose zĂ«vendĂ«sim. NĂ« parim, çdo qasje ka fusha tĂ« saj pĂ«rdorimi. PĂ«r ndryshime atomike, zĂ«vendĂ«simi Ă«shtĂ« mĂ« i preferuar, ndryshe duhet tĂ« pĂ«rdoret patch strategjik nĂ«pĂ«rmjet aplikimit. NĂ« rastin mĂ« tĂ« keq shpresoj se keni kuptuar se nuk duhet t'i besoni Google ose StackOverflow kur kĂ«rkoni "kubernetes apply vs replace". TĂ« paktĂ«n deri sa ky artikull tĂ« zĂ«vendĂ«sojĂ« pĂ«rgjigjen aktuale.

Krahasimi i saktë i Kubernetes Apply, Replace dhe Patch

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster