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.
če 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 PUT
и PATCH
... Kamor update
и replace
uporabo PUT
In 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, kubectl
je 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 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 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 apply
do 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 apply
To 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 edit
In 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č patch
da 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: 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
boapplication/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.
Vir: www.habr.com