Ustrezna primerjava Kubernetes Apply, Replace in Patch

Kubernetes ima več možnosti za posodabljanje virov: uporabi, uredi, popravi in ​​zamenjaj. Obstaja zmeda glede tega, kaj vsak počne in kdaj jih uporabiti. Ugotovimo.

Ustrezna primerjava Kubernetes Apply, Replace in Patch

če iskanje v Googlu se nahaja fraza "kubernetes apply vs replace". odgovori na StackOverflow, kar ni pravilno. Pri iskanju "kubernetes apply vs patch" prva povezava je dokumentacija za kubectl patch, ki ne vključuje primerjave apply и patch. Ta članek bo obravnaval različne možnosti in pravilno uporabo vsake od njih.

Med življenjskim ciklom vira Kubernetes (storitev, uvedba, vstop itd.) morate včasih spremeniti, dodati ali odstraniti nekatere lastnosti tega vira. Na primer, dodajte opombo, povečajte ali zmanjšajte število replik.

Kubernetes CLI

Če že delate z gručami Kubernetes prek CLI, že poznate apply и edit. Ekipa apply prebere specifikacijo vira iz datoteke in naredi "upsert" v gručo Kubernetes, tj. ustvari vir, če ne obstaja, in ga posodobi, če obstaja. Ekipa edit prebere vir prek API-ja, nato zapiše specifikacijo vira v lokalno datoteko, ki se nato odpre v urejevalniku besedil. Ko uredite in shranite datoteko, kubectl bo poslal narejene spremembe nazaj prek API-ja, ki bo skrbno uporabil te spremembe v viru.

Vsi ne poznajo ukazov patch и replace. Ekipa patch vam omogoča, da spremenite del specifikacije vira, pri čemer zagotovite samo spremenjeni del v ukazni vrstici. Ekipa replace deluje enako kot edit, vendar je treba vse narediti ročno: prenesti morate trenutno različico specifikacije vira, na primer z uporabo kubectl get -o yaml, uredite in nato uporabite replace za posodobitev vira v skladu s spremenjeno specifikacijo. Ekipa replace ne bo delovalo, če je med branjem in zamenjavo vira prišlo do kakršnih koli sprememb.

API Kubernetes

Verjetno poznate metode CoreV1().Pods().Update(), replaceNamespacedService ali patch_namespaced_deployment, če delate z gručami prek odjemalska knjižnica za Kubernetes API z uporabo nekega programskega jezika. Knjižnica obravnava te metode prek zahtev HTTP z uporabo metod PUT и PATCH... Kamor update и replace uporabo PUTIn patch, ne glede na to, kako nepomembna je lahko, uporablja PATCH.

Opozoriti je treba, da je kubectl deluje tudi z grozdi prek API-ja. Z drugimi besedami, kubectlje ovoj na vrhu odjemalske knjižnice za jezik Go, ki poleg standardnih zmožnosti API-ja v veliki meri zagotavlja možnost zagotavljanja podukazov v bolj kompaktni in berljivi obliki. Na primer, kot ste morda že opazili, metoda apply ni bil omenjen zgoraj v prejšnjem odstavku. Trenutno (maj 2020, pribl. prevajalec) vsa logika kubectl apply, tj. ustvarjanje neobstoječih virov in posodabljanje obstoječih, deluje v celoti na strani kode kubectl. Prizadevanja so vložena na logičnem prenosu apply na strani API-ja, vendar je še vedno v beta različici. Bom podrobneje napisal spodaj.

Privzeti popravek

Najbolje rabljeno patch, če želite posodobiti vir. Tako delujeta obe odjemalski knjižnici na API-ju Kubernetes in kubectl (ni presenetljivo, saj je ovoj za odjemalsko knjižnico, pribl. prevajalec).

Delajte strateško

Vse ekipe kubectl apply, edit и patch uporabite metodo PATCH v zahtevah HTTP za posodobitev obstoječega vira. Če se podrobneje poglobite v izvajanje ukazov, potem vsi uporabljajo pristop popravljanje strateškega spajanja za posodobitev virov, čeprav ukaz patch lahko uporabi druge pristope (več o tem spodaj). Pristop popravkov s strateškim združevanjem poskuša "dobiti vse pravilno" z združitvijo dobavljene specifikacije z obstoječo specifikacijo. Natančneje, poskuša združiti tako predmete kot nize, kar pomeni, da so spremembe ponavadi seštevalne. Na primer izvajanje ukaza patch z novo spremenljivko okolja v specifikaciji vsebnika pod, povzroči, da se ta spremenljivka okolja doda obstoječim spremenljivkam okolja, namesto da bi jih prepisala. Če želite odstraniti s tem pristopom, morate vrednost parametra v podani specifikaciji prisiliti na nič. Katera od ekip kubectl Ali je najbolje uporabiti za posodabljanje?

Če ustvarjate in upravljate svoje vire z uporabo kubectl apply, pri posodabljanju je bolje vedno uporabljati kubectl applydo kubectl lahko upravlja konfiguracijo in pravilno sledi zahtevanim spremembam od aplikacije do aplikacije. Prednost vedno uporabljajte apply je, da spremlja predhodno uporabljeno specifikacijo, kar mu omogoča, da ve, kdaj so specifikacijske lastnosti in elementi polja eksplicitno odstranjeni. To vam omogoča uporabo apply odstraniti lastnosti in elemente matrike, medtem ko običajno strateško spajanje ne bo delovalo. Ekipe edit и patch ne posodabljajte zapiskov, ki kubectl apply uporablja za sledenje svojim spremembam, tako da vse spremembe, ki se spremljajo in izvajajo prek API-ja Kubernetes, vendar so narejene prek ukazov edit и patch, neviden za naslednje ukaze applyTo pomeni, da apply jih ne odstrani, tudi če niso prikazani v specifikaciji vnosa za apply (To piše v dokumentaciji edit и patch posodobite uporabljene zapiske apply, v praksi pa - ne).

Če ne uporabite ukaza apply, se lahko uporablja kot editIn patch, pri čemer izberete ukaz, ki najbolj ustreza izvedeni spremembi. Pri dodajanju in spreminjanju lastnosti kosovnice sta oba pristopa približno enaka. Pri brisanju specifikacijskih lastnosti ali elementov polja edit se obnaša kot enkraten zagon apply, vključno s spremljanjem, kakšna je bila specifikacija pred in po tem, ko je bila urejena, tako da lahko izrecno odstranite lastnosti in elemente polja iz vira. V specifikaciji za morate vrednost lastnosti izrecno nastaviti na nič patchda ga odstranite iz vira. Odstranjevanje elementa matrike s popravki strateškega spajanja je bolj zapleteno, ker zahteva uporabo direktiv spajanja. Spodaj si oglejte druge pristope nadgradnje za bolj izvedljive alternative.

Za implementacijo metod posodabljanja v odjemalski knjižnici, ki se obnašajo podobno kot zgornji ukazi kubectl, morate nastaviti v zahtevah content-type в application/strategic-merge-patch+json. Če želite odstraniti lastnosti v specifikaciji, morate njihove vrednosti izrecno nastaviti na nič na podoben način kubectl patch. Če morate odstraniti elemente polja, morate v specifikacijo posodobitve vključiti direktive za združevanje ali uporabiti drugačen pristop k posodobitvam.

Drugi pristopi k posodobitvam

Kubernetes podpira dva druga pristopa posodabljanja: Popravek spajanja JSON и JSON popravek. Pristop popravkov spajanja JSON kot vhod vzame delno specifikacijo Kubernetes in podpira združevanje predmetov, podobno pristopu popravkov strateškega spajanja. Razlika med obema je v tem, da podpira samo zamenjavo matrike, vključno z matriko vsebnika v specifikaciji pod. To pomeni, da morate pri uporabi spajalnega popravka JSON zagotoviti popolne specifikacije za vse vsebnike, če se katera koli lastnost katerega koli vsebnika spremeni. Ta pristop je torej uporaben za odstranjevanje elementov iz niza v kosovnici. V ukazni vrstici lahko izberete popravek spajanja JSON z uporabo kubectl patch --type=merge. Pri delu z API-jem Kubernetes morate uporabiti metodo zahteve PATCH in namestitev content-type в application/merge-patch+json.

Pristop popravka JSON namesto zagotavljanja delne specifikacije vira uporablja zagotavljanje sprememb, ki jih želite narediti v viru, kot matriko, v kateri vsak element matrike predstavlja opis spremembe, ki je bila narejena v viru. Ta pristop je prožnejši in zmogljivejši način za izražanje izvedenih sprememb, vendar za ceno seznama izvedenih sprememb v ločenem formatu, ki ni Kubernetes, namesto pošiljanja delne specifikacije vira. IN kubectl popravek JSON lahko izberete z uporabo kubectl patch --type=json. Pri uporabi API-ja Kubernetes ta pristop deluje z uporabo metode zahteve PATCH in namestitev content-type в application/json-patch+json.

Potrebujemo zaupanje - uporabite zamenjavo

V nekaterih primerih se morate prepričati, da vir ni spremenjen med časom, ko je vir prebran, in njegovo posodobitvijo. Z drugimi besedami, zagotoviti morate, da bodo vse spremembe atomsko. V tem primeru morate za posodobitev virov uporabiti replace. Na primer, če imate ConfigMap s števcem, ki ga posodablja več virov, morate biti prepričani, da dva vira ne posodobita števca hkrati, zaradi česar se posodobitev izgubi. Za prikaz si zamislite zaporedje dogodkov z uporabo pristopa patch:

  • A in B pridobita trenutno stanje vira iz API-ja
  • Vsaka lokalno posodobi specifikacijo tako, da poveča števec za eno in doda "A" oziroma "B" v opombo "posodobljen do".
  • In posodablja vir nekoliko hitreje
  • B posodobi vir

Posledično je posodobitev A izgubljena. Zadnja operacija patch zmaga, števec se poveča za ena namesto za dve, vrednost opombe "updated-by" pa se konča z "B" in ne vsebuje "A". Primerjajmo zgoraj navedeno s tem, kaj se zgodi, ko se posodobitve izvedejo s tem pristopom replace:

  • A in B pridobita trenutno stanje vira iz API-ja
  • Vsaka lokalno posodobi specifikacijo tako, da poveča števec za eno in doda "A" oziroma "B" v opombo "posodobljen do".
  • In posodablja vir nekoliko hitreje
  • B poskuša posodobiti vir, vendar API posodobitev zavrne, ker je različica vira v specifikaciji replace se ne ujema s trenutno različico vira v Kubernetesu, ker je bila različica vira povečana z A-jevo operacijo zamenjave.

V zgornjem primeru bo moral B znova pridobiti vir, spremeniti novo stanje in poskusiti znova replace. To bo povzročilo, da se števec poveča za dva in opomba "posodobljen do" na koncu vključuje "AB".

Zgornji primer pomeni, da pri izvajanju replace Celoten vir je popolnoma zamenjan. Specifikacija, ki se uporablja za replace, ne sme biti delna ali po delih kot v apply, vendar popolno, vključno z dodatkom resourceVersion v metapodatke specifikacije. Če niste omogočili resourceVersion ali različica, ki jo posredujete, ni aktualna, bo zamenjava zavrnjena. Najboljši pristop k uporabi je torej replace – preberite vir, ga posodobite in takoj zamenjajte. Uporaba kubectl, lahko izgleda takole:

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

Omeniti velja, da se bosta naslednja dva ukaza, izvedena zaporedno, uspešno izvedla, saj deployment.yaml ne vsebuje lastnine .metadata.resourceVersion

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

Zdi se, da je to v nasprotju z zgoraj navedenim, tj. "dodajanje resourceVersion v specifikacijske metapodatke." Ali je to napačno reči? Ne, ni, ker če kubectl obvestila, ki jih niste navedli resourceVersion, ga bo prebral iz vira in ga dodal specifikaciji, ki ste jo podali, ter ga šele nato izvedel replace. Ker je to potencialno nevarno, če se zanašate na atomičnost, čarovnija deluje povsem ob strani kubectl, se nanj ne smete zanašati, ko uporabljate odjemalske knjižnice, ki delujejo z API-jem. V tem primeru boste morali prebrati trenutno specifikacijo vira, jo posodobiti in nato izvesti PUT prošnja.

Ne morete opraviti popravka – mi zamenjamo

Včasih morate narediti nekaj sprememb, ki jih API ne more obdelati. V teh primerih lahko vsilite zamenjavo vira tako, da ga izbrišete in znova ustvarite. To se naredi z uporabo kubectl replace --force. Zagon ukaza takoj odstrani vire in jih nato znova ustvari iz podane specifikacije. V API-ju ni upravljalnika za »prisilno zamenjavo« in če želite to narediti prek API-ja, morate izvesti dve operaciji. Najprej morate izbrisati vir z nastavitvijo zanj gracePeriodSeconds na nič (0) in propagationPolicy v »Ozadje« in nato znova ustvarite ta vir z želeno specifikacijo.

Opozorilo: ta pristop je potencialno nevaren in lahko vodi v nedefinirano stanje.

Prijavite se na strani strežnika

Kot že omenjeno, razvijalci Kubernetes delajo na implementaciji logike apply z dne kubectl v Kubernetes API. Logike apply na voljo v Kubernetesu 1.18 prek kubectl apply --server-side ali prek API-ja z uporabo metode PATCH с content-type application/apply-patch+YAML.

Opomba: JSON je tudi veljaven YAML, tako da lahko pošljete specifikacijo kot JSON, tudi če content-type bo application/apply-patch+yaml.

Poleg te logike kubectl postane na voljo vsem prek API-ja, apply na strani strežnika spremlja, kdo je odgovoren za polja v specifikaciji, s čimer omogoča varen večkratni dostop za njeno urejanje brez konfliktov. Z drugimi besedami, če apply na strežniški strani bo postal bolj razširjen, pojavil se bo univerzalni varen vmesnik za upravljanje virov za različne odjemalce, na primer kubectl, Pulumi ali Terraform, GitOps, pa tudi samonapisane skripte z uporabo odjemalskih knjižnic.

Rezultati

Upam, da vam je bil ta kratek pregled različnih načinov posodabljanja virov v gručah v pomoč. Dobro je vedeti, da ni samo uporaba proti zamenjavi; mogoče je vir posodobiti z uporabo, urejanjem, popravkom ali zamenjavo. Konec koncev ima načeloma vsak pristop svoje področje uporabe. Za atomske spremembe je bolje zamenjati; drugače uporabite popravek strateškega združevanja prek uporabe. Vsaj pričakujem, da razumete, da ne morete zaupati Googlu ali StackOerflowu, ko iščete »kubernetes apply vs replace«. Vsaj dokler ta članek ne nadomesti trenutnega odgovora.

Ustrezna primerjava Kubernetes Apply, Replace in Patch

Vir: www.habr.com

Dodaj komentar