Krahasimi i duhur i Kubernetes Apliko, Zëvendëso dhe Patch

Kubernetes ka disa opsione për përditësimin e burimeve: aplikoni, modifikoni, rregulloni dhe zëvendësoni. Ekziston një konfuzion rreth asaj që bën secili dhe kur t'i përdorë ato. Le ta kuptojmë.

Krahasimi i duhur i Kubernetes Apliko, Zëvendëso dhe Patch

Nëse kërkoni në Google ndodhet shprehja "kubernetes aplikojnë vs zëvendësojnë". përgjigjuni StackOverflow, e cila nuk është e saktë. Kur kërkoni "kubernetes application vs patch" lidhja e parë është dokumentacioni për të kubectl patch, e cila nuk përfshin krahasimin apply и patch. Ky artikull do të shqyrtojë opsionet e ndryshme, si dhe përdorimin e duhur të secilës prej tyre.

Gjatë ciklit jetësor të një burimi Kubernetes (shërbim, vendosje, hyrje, etj.), ndonjëherë ju duhet të ndryshoni, shtoni ose hiqni disa veti të këtij burimi. Për shembull, shtoni një shënim, rrisni ose ulni numrin e kopjeve.

Kubernetes CLI

Nëse tashmë jeni duke punuar me grupimet e Kubernetes nëpërmjet CLI, tashmë jeni njohur apply и edit. Ekipi apply lexon specifikimin e burimit nga skedari dhe bën një "përmbysje" në grupin Kubernetes, d.m.th. krijon burimin nëse nuk ekziston dhe e përditëson nëse ekziston. Ekipi edit lexon një burim nëpërmjet API, pastaj shkruan specifikimin e burimit në një skedar lokal, i cili më pas hapet në një redaktues teksti. Pasi të redaktoni dhe ruani skedarin, kubectl do të dërgojë ndryshimet e bëra përsëri përmes API-së, e cila do t'i zbatojë me kujdes këto ndryshime në burim.

Jo të gjithë i dinë komandat patch и replace. Ekipi patch ju lejon të ndryshoni një pjesë të specifikimit të burimit, duke siguruar vetëm pjesën e ndryshuar në vijën e komandës. Ekipi replace funksionon njësoj si edit, por gjithçka duhet të bëhet me dorë: duhet të shkarkoni versionin aktual të specifikimit të burimit, për shembull, duke përdorur kubectl get -o yaml, modifikojeni, më pas përdorni replace për të përditësuar një burim sipas një specifikimi të ndryshuar. Ekipi replace nuk do të funksionojë nëse ka ndodhur ndonjë ndryshim midis leximit dhe zëvendësimit të burimit.

Kubernetes API

Ju ndoshta jeni njohur me metodat CoreV1().Pods().Update(), replaceNamespacedService ose patch_namespaced_deployment, nëse punoni me grupe nëpërmjet biblioteka e klientit për Kubernetes API duke përdorur një gjuhë programimi. Biblioteka i trajton këto metoda nëpërmjet kërkesave HTTP duke përdorur metodat PUT и PATCH... Ku update и replace përdorim PUTDhe patch, sado e parëndësishme të jetë, përdor PATCH.

Ajo duhet të theksohet se kubectl punon edhe me grupe nëpërmjet API. Me fjale te tjera, kubectlështë një mbështjellës në krye të bibliotekës së klientit për gjuhën Go, e cila në masë të madhe ofron mundësinë për të ofruar nënkomanda në një formë më kompakte dhe më të lexueshme, përveç aftësive standarde API. Për shembull, siç mund ta keni vënë re tashmë, metoda apply nuk u përmend më lart në paragrafin e mëparshëm. Aktualisht (maj 2020, përafërsisht. përkthyes) gjithë logjikën kubectl apply, d.m.th. krijimi i burimeve joekzistente dhe përditësimi i atyre ekzistuese, funksionon tërësisht në anën e kodit kubectl. Po bëhen përpjekje mbi transferimin logjik apply në anën API, por është ende në beta. Më poshtë do të shkruaj më hollësisht.

Patch si parazgjedhje

Përdoret më së miri patch, nëse dëshironi të përditësoni burimin. Kështu funksionojnë të dy bibliotekat e klientëve në krye të Kubernetes API dhe kubectl (nuk është për t'u habitur, pasi është një mbështjellës për bibliotekën e klientit, përafërsisht. përkthyes).

Punoni në mënyrë strategjike

Të gjitha ekipet kubectl apply, edit и patch përdorni metodën PATCH në HTTP kërkon të përditësojë një burim ekzistues. Nëse gërmoni në zbatimin e komandave në më shumë detaje, atëherë të gjithë përdorin qasjen arnimi strategjik-bashkimi për të përditësuar burimet, edhe pse komanda patch mund të përdorë qasje të tjera (më shumë për këtë më poshtë). Qasja e korrigjimit të bashkimit strategjik përpiqet të "marrë atë siç duhet" duke bashkuar specifikimin e dhënë me specifikimin ekzistues. Më konkretisht, ai përpiqet të kombinojë të dy objektet dhe vargjet, që do të thotë se ndryshimet priren të jenë shtesë. Për shembull, ekzekutimi i komandës patch me një ndryshore të re mjedisi në specifikimin e kontejnerit të pod, bën që ajo ndryshore e mjedisit të shtohet në variablat ekzistuese të mjedisit në vend që t'i mbishkruhet ato. Për të hequr duke përdorur këtë qasje, duhet të detyroni vlerën e parametrit të zhvlerësohet në specifikimin e dhënë. Cila nga skuadrat kubectl A është më mirë të përdoret për përditësim?

Nëse krijoni dhe menaxhoni burimet tuaja duke përdorur kubectl apply, kur përditësoni është më mirë të përdorni gjithmonë kubectl applyashtu që kubectl mund të menaxhojë konfigurimin dhe të gjurmojë saktë ndryshimet e kërkuara nga aplikacioni në aplikacion. Avantazhi përdorni gjithmonë apply është se ai mban gjurmët e një specifikimi të aplikuar më parë, duke e lejuar atë të dijë kur veçoritë e specifikimit dhe elementët e grupit hiqen në mënyrë eksplicite. Kjo ju lejon të përdorni apply për të hequr veçoritë dhe elementët e grupit, ndërkohë që një bashkim normal strategjik nuk do të funksionojë. Ekipet edit и patch mos përditësoni shënimet që kubectl apply përdor për të gjurmuar ndryshimet e tij, kështu që çdo ndryshim që gjurmohet dhe bëhet përmes API-së së Kubernetes, por bëhet përmes komandave edit и patch, i padukshëm për komandat pasuese applyqë është apply nuk i heq ato edhe nëse nuk shfaqen në specifikimet e hyrjes për apply (Dokumentacioni e thotë këtë edit и patch bëni përditësime për shënimet e përdorura apply, por në praktikë - jo).

Nëse nuk e përdorni komandën apply, mund të përdoret si editDhe patch, duke zgjedhur komandën që i përshtatet më mirë ndryshimit që po bëhet. Kur shtoni dhe ndryshoni vetitë e BOM, të dyja qasjet janë afërsisht të njëjta. Kur fshini vetitë e specifikimit ose elementët e grupit edit sillet si një lëshim një herë apply, duke përfshirë mbajtjen e shënimeve se si ishte specifikimi përpara dhe pas modifikimit të tij, në mënyrë që të mund të hiqni në mënyrë eksplicite vetitë dhe elementët e grupit nga një burim. Ju duhet të vendosni në mënyrë eksplicite vlerën e pronës si null në specifikimin për patchpër ta hequr atë nga burimi. Heqja e një elementi grupi duke përdorur korrigjimin e bashkimit strategjik është më kompleks sepse kërkon përdorimin e direktivave të bashkimit. Shihni qasjet e tjera të përmirësimit më poshtë për alternativa më të qëndrueshme.

Për të zbatuar metoda të përditësimit në bibliotekën e klientit që sillen në mënyrë të ngjashme me komandat e mësipërme kubectl, duhet të vendoset në kërkesa content-type в application/strategic-merge-patch+json. Nëse dëshironi të hiqni vetitë në një specifikim, duhet të vendosni qartë vlerat e tyre në null në një mënyrë të ngjashme kubectl patch. Nëse keni nevojë të hiqni elementët e grupit, duhet të përfshini direktivat e bashkimit në specifikimin e përditësimit ose të përdorni një qasje të ndryshme ndaj përditësimeve.

Qasje të tjera ndaj përditësimeve

Kubernetes mbështet dy qasje të tjera të përditësimit: Arnimi i bashkimit JSON и Patch JSON. Qasja e patch-it të bashkimit JSON merr një specifikim të pjesshëm të Kubernetes si hyrje dhe mbështet bashkimin e objekteve të ngjashme me qasjen e korrigjimit të bashkimit strategjik. Dallimi midis të dyve është se ai mbështet vetëm zëvendësimin e grupeve, duke përfshirë grupin e kontejnerëve në specifikimin e pod. Kjo do të thotë që kur përdorni një patch bashkimi JSON, duhet të siguroni specifikime të plota për të gjithë kontejnerët në rast se ndryshon ndonjë veçori e ndonjë kontejneri. Pra, kjo qasje është e dobishme për heqjen e elementeve nga një grup në një BOM. Në vijën e komandës mund të zgjidhni patch-in e bashkimit JSON duke përdorur kubectl patch --type=merge. Kur punoni me Kubernetes API, duhet të përdorni metodën e kërkesës PATCH dhe instalimi content-type в application/merge-patch+json.

Qasja patch JSON, në vend që të sigurojë një specifikim të pjesshëm të një burimi, përdor sigurimin e ndryshimeve që dëshironi të bëni në burim si një grup, në të cilin çdo element i grupit përfaqëson një përshkrim të ndryshimit që po i bëhet burimit. Kjo qasje është një mënyrë më fleksibël dhe më e fuqishme për të shprehur ndryshimet që po bëhen, por me koston e listimit të ndryshimeve që bëhen në një format të veçantë, jo-Kubernetes, në vend të dërgimit të një specifikimi të pjesshëm të burimit. NË kubectl ju mund të zgjidhni patch JSON duke përdorur kubectl patch --type=json. Kur përdorni Kubernetes API, kjo qasje funksionon duke përdorur metodën e kërkesës PATCH dhe instalimi content-type в application/json-patch+json.

Ne kemi nevojë për besim - përdorni zëvendësoni

Në disa raste, duhet të jeni të sigurt që nuk bëhen ndryshime në një burim midis kohës kur lexohet burimi dhe kur ai përditësohet. Me fjalë të tjera, duhet të siguroheni që të gjitha ndryshimet do të jenë atomike. Në këtë rast, për të përditësuar burimet duhet të përdorni replace. Për shembull, nëse keni një ConfigMap me një numërues që përditësohet nga burime të shumta, duhet të jeni të sigurt që dy burime nuk e përditësojnë numëruesin në të njëjtën kohë, duke bërë që përditësimi të humbasë. Për të demonstruar, imagjinoni një sekuencë ngjarjesh duke përdorur qasjen patch:

  • A dhe B marrin gjendjen aktuale të burimit nga API
  • Secili përditëson në nivel lokal specifikimet duke e rritur numëruesin me një dhe gjithashtu duke shtuar "A" ose "B" përkatësisht në shënimin "përditësuar nga"
  • Dhe ai përditëson burimin pak më shpejt
  • B përditëson burimin

Si rezultat, përditësimi A humbet. Operacioni i fundit patch fiton, numëruesi rritet me një në vend të dy, dhe vlera e shënimit "përditësuar nga" përfundon me "B" dhe nuk përmban "A". Le të krahasojmë sa më sipër me atë që ndodh kur përditësimet bëhen duke përdorur qasjen replace:

  • A dhe B marrin gjendjen aktuale të burimit nga API
  • Secili përditëson në nivel lokal specifikimet duke e rritur numëruesin me një dhe gjithashtu duke shtuar "A" ose "B" përkatësisht në shënimin "përditësuar nga"
  • Dhe ai përditëson burimin pak më shpejt
  • B përpiqet të përditësojë burimin, por përditësimi refuzohet nga API sepse versioni i burimit është në specifikim replace nuk përputhet me versionin aktual të burimit në Kubernetes sepse versioni i burimit u rrit nga operacioni i zëvendësimit të A.

Në rastin e mësipërm, B do të duhet të rimarr burimin, të bëjë ndryshime në gjendjen e re dhe të provojë përsëri replace. Kjo do të bëjë që numëruesi të rritet me dy dhe shënimi "përditësuar nga" të përfshijë "AB" në fund.

Shembulli i mësipërm nënkupton që gjatë ekzekutimit replace I gjithë burimi është zëvendësuar plotësisht. Specifikimi i përdorur për replace, nuk duhet të jetë i pjesshëm, ose pjesërisht si në apply, por i plotë, duke përfshirë shtesën resourceVersion në meta të dhënat e specifikimeve. Nëse nuk e keni aktivizuar resourceVersion ose versioni që jepni nuk është aktual, zëvendësimi do të refuzohet. Pra, qasja më e mirë për t'u përdorur është replace – lexoni burimin, përditësoni dhe zëvendësojeni menjëherë. Duke përdorur kubectl, 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 -

Vlen të theksohet se dy komandat e mëposhtme, të ekzekutuara në mënyrë sekuenciale, do të ekzekutohen me sukses, pasi deployment.yaml nuk përmban pronë .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ë lart, d.m.th. " duke shtuar resourceVersion në metadatat e specifikimeve." A është gabim të thuhet kështu? Jo, nuk është, sepse nëse kubectl njoftime që nuk i keni specifikuar resourceVersion, do ta lexojë atë nga burimi dhe do ta shtojë në specifikimin që keni specifikuar dhe vetëm atëherë do ta ekzekutojë atë replace. Për shkak se kjo është potencialisht e rrezikshme nëse mbështeteni në atomicitetin, magjia funksionon tërësisht në anën kubectl, nuk duhet të mbështeteni në të kur përdorni bibliotekat e klientëve që punojnë me API. Në këtë rast do t'ju duhet të lexoni specifikimin aktual të burimit, ta përditësoni dhe më pas ta ekzekutoni PUT kërkesë.

Ju nuk mund të bëni një patch - ne bëjmë një zëvendësim

Ndonjëherë ju duhet të bëni disa ndryshime që nuk mund të trajtohen nga API. Në këto raste, ju mund të detyroni zëvendësimin e burimit duke e fshirë dhe rikrijuar atë. Kjo bëhet duke përdorur kubectl replace --force. Ekzekutimi i komandës heq menjëherë burimet dhe më pas i rikrijon ato nga specifikimi i dhënë. Nuk ka asnjë mbajtës "zëvendësimi me forcë" në API, dhe për ta bërë këtë përmes API-së, duhet të kryeni dy operacione. Së pari ju duhet të fshini burimin duke e vendosur atë gracePeriodSeconds në zero (0) dhe propagationPolicy në "Sfondi" dhe më pas rikrijoni këtë burim me specifikimin e dëshiruar.

Paralajmërim: Kjo qasje është potencialisht e rrezikshme dhe mund të çojë në një gjendje të papërcaktuar.

Aplikoni në anën e serverit

Siç u përmend më lart, zhvilluesit e Kubernetes po punojnë për zbatimin e logjikës apply nga kubectl në Kubernetes API. Logjikat apply në dispozicion në Kubernetes 1.18 nëpërmjet kubectl apply --server-side ose nëpërmjet API-së duke përdorur metodën PATCH с content-type application/apply-patch+YAML.

Shënim: JSON është gjithashtu i vlefshëm YAML, kështu që ju mund ta dërgoni specifikimin si JSON edhe nëse content-type do të application/apply-patch+yaml.

Përveç kësaj logjike kubectl bëhet i disponueshëm për të gjithë nëpërmjet API, apply në anën e serverit, mban gjurmët se kush është përgjegjës për fushat në specifikim, duke lejuar kështu akses të shumëfishtë të sigurt për redaktimin e tij pa konflikte. Me fjalë të tjera, nëse apply në anën e serverit do të bëhet më i përhapur, një ndërfaqe universale e menaxhimit të burimeve do të shfaqet për klientë të ndryshëm, për shembull, kubectl, Pulumi ose Terraform, GitOps, si dhe skriptet e shkruara vetë duke përdorur bibliotekat e klientëve.

Rezultatet e

Shpresoj se kjo përmbledhje e shkurtër e mënyrave të ndryshme për të përditësuar burimet në grupe ishte e dobishme për ju. Është mirë të dini se nuk është vetëm aplikimi kundrejt zëvendësimit; është e mundur të përditësoni një burim duke përdorur aplikoni, modifikoni, korrigjoni ose zëvendësoni. Në fund të fundit, në parim, secila qasje ka fushën e saj të aplikimit. Për ndryshimet atomike, zëvendësimi është i preferueshëm; përndryshe, duhet të përdorni patch-in e bashkimit strategjik nëpërmjet aplikimit. Së paku, unë pres që ju të kuptoni se nuk mund t'i besoni Google ose StackOerflow kur kërkoni për "kubernetes aplikoni kundër zëvendësimit". Të paktën derisa ky artikull të zëvendësojë përgjigjen aktuale.

Krahasimi i duhur i Kubernetes Apliko, Zëvendëso dhe Patch

Burimi: www.habr.com

Shto një koment