Kubernetes ima nekoliko opcija za ažuriranje resursa: primijeniti, urediti, zakrpiti i zamijeniti. Postoji konfuzija oko toga šta svaki od njih radi i kada ih koristiti. Hajde da to shvatimo.
ako kubectl patch
, što ne uključuje poređenje apply
и patch
. Ovaj članak će razmotriti različite opcije, kao i pravilnu upotrebu svake od njih.
Tokom životnog ciklusa Kubernetes resursa (usluga, implementacija, ulaz, itd.), ponekad morate promijeniti, dodati ili ukloniti neka svojstva ovog resursa. Na primjer, dodajte bilješku, povećajte ili smanjite broj replika.
Kubernetes CLI
Ako već radite sa Kubernetes klasterima preko CLI-a, već ste upoznati apply
и edit
. Tim apply
čita specifikaciju resursa iz datoteke i pravi "upsert" u Kubernetes klaster, tj. kreira resurs ako ne postoji i ažurira ga ako postoji. Tim edit
čita resurs preko API-ja, zatim upisuje specifikaciju resursa u lokalnu datoteku, koja se zatim otvara u uređivaču teksta. Nakon što uredite i sačuvate datoteku, kubectl
će poslati promjene napravljene nazad kroz API, koji će pažljivo primijeniti ove promjene na resurs.
Ne znaju svi komande patch
и replace
. Tim patch
omogućava vam da promijenite dio specifikacije resursa, pružajući samo promijenjeni dio na komandnoj liniji. Tim replace
radi isto kao edit
, ali sve treba učiniti ručno: morate preuzeti trenutnu verziju specifikacije resursa, na primjer, koristeći kubectl get -o yaml
, uredite ga, a zatim koristite replace
da ažurirate resurs prema promijenjenoj specifikaciji. Tim replace
neće raditi ako je došlo do bilo kakvih promjena između čitanja i zamjene resursa.
Kubernetes API
Vjerovatno ste upoznati sa metodama CoreV1().Pods().Update()
, replaceNamespacedService
ili patch_namespaced_deployment
, ako radite s klasterima preko PUT
и PATCH
... U čemu update
и replace
koristiti PUT
i patch
, koliko god to bilo trivijalno, koristi PATCH
.
Vredi napomenuti kubectl
također radi sa klasterima preko API-ja. Drugim riječima, kubectl
je omotač na vrhu klijentske biblioteke za jezik Go, koji u velikoj mjeri pruža mogućnost pružanja podnaredbi u kompaktnijem i čitljivijem obliku pored standardnih API mogućnosti. Na primjer, kao što ste možda već primijetili, metoda apply
nije pomenuto gore u prethodnom paragrafu. Trenutno (maj 2020. cca. prevodilac) sva logika kubectl apply
, tj. kreiranje nepostojećih resursa i ažuriranje postojećih, radi u potpunosti na strani koda kubectl
. Ulažu se napori apply
na API stranu, ali je još uvijek u beta verziji. U nastavku ću pisati detaljnije.
Zakrpa po defaultu
Najbolje korišteno patch
, ako želite ažurirati resurs. Ovako rade obje klijentske biblioteke na vrhu Kubernetes API-ja i kubectl
(nije iznenađujuće, pošto je to omot za klijentsku biblioteku, cca. prevodilac).
Radite strateški
Svi timovi kubectl
apply
, edit
и patch
koristite metodu PATCH
u HTTP zahtjevima za ažuriranje postojećeg resursa. Ako se detaljnije zadubite u implementaciju naredbi, onda sve koriste pristup patch
mogu koristiti druge pristupe (više o tome u nastavku). Pristup strateškog spajanja zakrpa pokušava da se "ispravi" spajanjem isporučene specifikacije sa postojećom specifikacijom. Preciznije, pokušava da kombinuje i objekte i nizove, što znači da promene imaju tendenciju da budu aditivne. Na primjer, pokretanje naredbe patch
sa novom varijablom okruženja u specifikaciji pod kontejnera, uzrokuje da se ta varijabla okruženja doda postojećim varijablama okruženja umjesto da ih prepiše. Da biste uklonili koristeći ovaj pristup, morate prisiliti vrijednost parametra na null u datoj specifikaciji. Koji od timova kubectl
Da li je najbolje koristiti za ažuriranje?
Ako kreirate i upravljate svojim resursima koristeći kubectl apply
, prilikom ažuriranja bolje je uvijek koristiti kubectl apply
u kubectl
mogao upravljati konfiguracijom i ispravno pratiti tražene promjene od aplikacije do aplikacije. Prednost uvijek koristite apply
je da prati prethodno primijenjenu specifikaciju, omogućavajući joj da zna kada su svojstva specifikacije i elementi niza eksplicitno uklonjeni. Ovo vam omogućava da koristite apply
za uklanjanje svojstava i elemenata niza, dok normalno strateško spajanje neće raditi. Timovi edit
и patch
ne ažuriraj bilješke koje kubectl apply
koristi za praćenje njegovih promjena, tako da sve promjene koje se prate i vrše putem Kubernetes API-ja, ali su napravljene putem naredbi edit
и patch
, nevidljiv za naredne komande apply
, to jest apply
ne uklanja ih čak i ako se ne pojavljuju u ulaznoj specifikaciji za apply
(To piše u dokumentaciji edit
и patch
izvršite ažuriranje korištenih bilješki apply
, ali u praksi - ne).
Ako ne koristite naredbu apply
, može se koristiti kao edit
, i patch
, birajući naredbu koja najbolje odgovara promjeni koja se vrši. Prilikom dodavanja i mijenjanja svojstava sastavnice, oba pristupa su otprilike ista. Prilikom brisanja svojstava specifikacije ili elemenata niza edit
ponaša se kao jednokratno lansiranje apply
, uključujući praćenje toga kakva je specifikacija bila prije i nakon što je uređena, tako da možete eksplicitno ukloniti svojstva i elemente niza iz resursa. Morate eksplicitno postaviti vrijednost svojstva na null u specifikaciji za patch
da ga uklonite sa resursa. Uklanjanje elementa niza pomoću zakrpa strateškog spajanja je složenije jer zahtijeva korištenje direktiva spajanja. Pogledajte druge pristupe nadogradnje u nastavku za održivije alternative.
Implementirati metode ažuriranja u biblioteci klijenta koje se ponašaju slično gornjim naredbama kubectl
, treba postaviti u zahtjevima content-type
в application/strategic-merge-patch+json
. Ako želite ukloniti svojstva u specifikaciji, morate eksplicitno postaviti njihove vrijednosti na null na sličan način kubectl patch
. Ako trebate ukloniti elemente niza, trebali biste uključiti direktive spajanja u specifikaciju ažuriranja ili koristiti drugačiji pristup ažuriranjima.
Drugi pristupi ažuriranju
Kubernetes podržava još dva pristupa ažuriranju: kubectl patch --type=merge
. Kada radite sa Kubernetes API-jem, trebali biste koristiti metodu zahtjeva PATCH
i instalaciju content-type
в application/merge-patch+json
.
Pristup JSON zakrpe, umjesto pružanja djelomične specifikacije resursa, koristi pružanje promjena koje želite napraviti na resursu kao niz, u kojem svaki element niza predstavlja opis promjene koja se vrši na resursu. Ovaj pristup je fleksibilniji i moćniji način za izražavanje promjena koje su napravljene, ali po cijenu navođenja izmjena koje su napravljene u zasebnom, ne-Kubernetes formatu, umjesto slanja djelomične specifikacije resursa. IN kubectl
možete odabrati JSON zakrpu koristeći kubectl patch --type=json
. Kada koristite Kubernetes API, ovaj pristup radi koristeći metodu zahtjeva PATCH
i instalaciju content-type
в application/json-patch+json
.
Treba nam samopouzdanje - koristite zamjenu
U nekim slučajevima morate biti sigurni da nema promjena na resursu između vremena čitanja resursa i ažuriranja. Drugim riječima, trebali biste biti sigurni da će sve promjene biti atomski. U ovom slučaju, za ažuriranje resursa trebate koristiti replace
. Na primjer, ako imate ConfigMap sa brojačem koji je ažuriran iz više izvora, trebali biste biti sigurni da dva izvora ne ažuriraju brojač u isto vrijeme, što uzrokuje gubitak ažuriranja. Da biste demonstrirali, zamislite niz događaja koristeći pristup patch
:
- A i B dobijaju trenutno stanje resursa iz API-ja
- Svaki lokalno ažurira specifikaciju povećanjem brojača za jedan i dodavanjem "A" ili "B" respektivno u napomenu "ažurirano od strane"
- I ažurira resurs malo brže
- B ažurira resurs
Kao rezultat toga, ažuriranje A je izgubljeno. Poslednja operacija patch
pobjeda, brojač se povećava za jedan umjesto za dva, a vrijednost napomene "ažurirano" završava se sa "B" i ne sadrži "A". Hajde da uporedimo gore navedeno sa onim što se dešava kada se ažuriranja izvrše korišćenjem ovog pristupa replace
:
- A i B dobijaju trenutno stanje resursa iz API-ja
- Svaki lokalno ažurira specifikaciju povećanjem brojača za jedan i dodavanjem "A" ili "B" respektivno u napomenu "ažurirano od strane"
- I ažurira resurs malo brže
- B pokušava ažurirati resurs, ali je ažuriranje odbijeno od strane API-ja jer je verzija resursa u specifikaciji
replace
ne odgovara trenutnoj verziji resursa u Kubernetesu jer je verzija resursa povećana operacijom zamjene A.
U gornjem slučaju, B će morati ponovo preuzeti resurs, izvršiti promjene u novom stanju i pokušati ponovo replace
. Ovo će uzrokovati povećanje brojača za dva i napomenu "ažurirano od strane" uključiti "AB" na kraju.
Gornji primjer implicira da prilikom izvršavanja replace
Cijeli resurs je u potpunosti zamijenjen. Specifikacija koja se koristi za replace
, ne smije biti djelomična, ili u dijelovima kao u apply
, ali kompletan, uključujući i dodatak resourceVersion
u metapodatke specifikacije. Ako niste omogućili resourceVersion
ili verzija koju navedete nije aktuelna, zamjena će biti odbijena. Dakle, najbolji pristup za korištenje je replace
– pročitajte izvor, ažurirajte ga i odmah ga zamijenite. Koristeći kubectl
, moglo bi izgledati ovako:
$ kubectl get deployment my-deployment -o json
| jq '.spec.template.spec.containers[0].env[1].value = "new value"'
| kubectl replace -f -
Vrijedi napomenuti da će se sljedeće dvije naredbe, koje se izvršavaju uzastopno, uspješno izvršiti, jer deployment.yaml
ne sadrži imovinu .metadata.resourceVersion
$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml
Čini se da je to u suprotnosti sa onim što je gore rečeno, tj. "dodavanje resourceVersion
u metapodatke specifikacije." Da li je pogrešno to reći? Ne, nije, jer ako kubectl
obavještenja koja niste naveli resourceVersion
, pročitat će ga iz izvora i dodati specifikaciji koju ste naveli, a tek onda izvršiti replace
. Budući da je ovo potencijalno opasno ako se oslanjate na atomičnost, magija djeluje u potpunosti sa strane kubectl
, ne biste se trebali oslanjati na njega kada koristite klijentske biblioteke koje rade s API-jem. U tom slučaju ćete morati pročitati trenutnu specifikaciju resursa, ažurirati je i zatim izvršiti PUT
zahtjev.
Ne možete napraviti zakrpu – mi vršimo zamjenu
Ponekad morate napraviti neke promjene kojima API ne može upravljati. U tim slučajevima možete prisiliti zamjenu resursa brisanjem i ponovnim kreiranjem. Ovo se radi pomoću kubectl replace --force
. Izvođenje naredbe odmah uklanja resurse, a zatim ih ponovo kreira iz isporučene specifikacije. U API-ju ne postoji rukovalac "prisilne zamjene", a da biste to učinili preko API-ja, potrebno je izvršiti dvije operacije. Prvo morate izbrisati resurs postavljanjem za njega gracePeriodSeconds
na nulu (0) i propagationPolicy
u „Pozadina“, a zatim ponovo kreirajte ovaj resurs sa željenom specifikacijom.
Upozorenje: Ovaj pristup je potencijalno opasan i može dovesti do nedefiniranog stanja.
Prijavite se na strani servera
Kao što je gore pomenuto, programeri Kubernetesa rade na implementaciji logike apply
из kubectl
u Kubernetes API-ju. Logika apply
dostupno u Kubernetes 1.18 putem kubectl apply --server-side
ili putem API-ja koristeći metodu PATCH
с content-type
application/apply-patch+YAML
.
Napomena: JSON je također važeći YAML, tako da možete poslati specifikaciju kao JSON čak i ako
content-type
će bitiapplication/apply-patch+yaml
.
Osim te logike kubectl
postaje dostupan svima putem API-ja, apply
na strani servera, prati ko je odgovoran za polja u specifikaciji, čime se omogućava siguran višestruki pristup za njegovo uređivanje bez sukoba. Drugim riječima, ako apply
na strani servera će se sve više proširiti, pojavit će se univerzalno sigurno sučelje za upravljanje resursima za različite klijente, na primjer, kubectl, Pulumi ili Terraform, GitOps, kao i samostalno pisane skripte koristeći klijentske biblioteke.
Ishodi
Nadam se da vam je ovaj kratki pregled različitih načina ažuriranja resursa u klasterima bio od pomoći. Dobro je znati da nije samo primjena nasuprot zamjeni; moguće je ažurirati resurs pomoću primjene, uređivanja, zakrpe ili zamjene. Uostalom, u principu, svaki pristup ima svoje područje primjene. Za atomske promjene poželjna je zamjena; u suprotnom, trebali biste koristiti zakrpu strateškog spajanja putem aplikacije. U najmanju ruku, očekujem da shvatite da ne možete vjerovati Google-u ili StackOerflow-u kada tražite "kubernetes primijeniti vs zamijeniti". Barem dok ovaj članak ne zamijeni trenutni odgovor.
izvor: www.habr.com