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ë.

NĂ«se fraza "kubernetes apply vs replace", do tĂ« gjeni , e cila nuk Ă«shtĂ« e saktĂ«. "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 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 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 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: dhe Praktika 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ërrimnuk 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.yamlKjo 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-typedo 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.

Burimi: habr.com
