Det finns flera sÀtt att uppdatera resurser för Kubernetes: apply, edit, patch och replace. Det rÄder viss förvirring kring vad var och en av dem gör och nÀr de ska anvÀndas. LÄt oss reda ut det.

Om frasen "kubernetes apply vs replace", hittas , vilket inte Àr korrekt. "kubernetes apply vs patch" Àr den första lÀnken - dokumentationen för kubectl patch, som inte inkluderar en jÀmförelse apply och patch. I denna artikel kommer de olika alternativen att diskuteras, liksom rÀtt anvÀndning av var och en av dem.
Under livscykeln för en Kubernetes-resurs (t.ex. tjÀnst, deployment, ingress, etc.) behövs det ibland att Àndra, lÀgga till eller ta bort vissa egenskaper frÄn denna resurs. Till exempel kan man behöva lÀgga till en anteckning eller öka eller minska antalet repliker.
Kubernetes CLI
Om du redan arbetar med Kubernetes-kluster via CLI, Àr du förmodligen bekant med apply och edit. Kommandot apply lÀser resursens specifikation frÄn en fil och gör en "upsert" i Kubernetes-klustret, det vill sÀga skapar resursen om den inte finns och uppdaterar den om den existerar. Kommandot edit lÀser resursen via API, och skriver sedan resursens specifikation till en lokal fil som sedan öppnas i en textredigerare. NÀr du har redigerat och sparat filen, kubectl skickar de gjorda Àndringarna tillbaka via API, som noggrant tillÀmpar dessa Àndringar pÄ resursen.
Inte alla kÀnner till kommandona patch och replace. Kommandot patch tillÄter att Àndra en del av resursens specifikation genom att endast tillhandahÄlla den Àndrade delen i kommandoraden. Kommandot replace fungerar pÄ samma sÀtt som edit, men allt mÄste göras manuellt: Man mÄste ladda ner den aktuella versionen av resursens specifikation, till exempel med kubectl get -o yaml, redigera den, och sedan anvÀnda replace för att uppdatera resursen med den Àndrade specifikationen. Kommandot replace kommer inte att fungera om det har skett nÄgra Àndringar mellan lÀsningen och ersÀttningen av resursen.
Kubernetes API
Du Àr förmodligen bekant med metoderna CoreV1().Pods().Update(), replaceNamespacedService eller patch_namespaced_deployment, om du arbetar med kluster via med anvÀndning av nÄgot programmeringssprÄk. Biblioteket hanterar dessa metoder via HTTP-förfrÄgningar, med anvÀndning av metoderna PUT och PATCH. Samtidigt update och replace anvÀnder PUT, och patch, hur banalt det Àn kan lÄta, anvÀnder PATCH.
Det Ă€r vĂ€rt att nĂ€mna att kubectl fungerar ocksĂ„ med kluster via API. Med andra ord, kubectlâ Ă€r en wrapper över klientbiblioteket för Go-sprĂ„ket som i stor utstrĂ€ckning ger möjlighet att erbjuda undermenyer pĂ„ ett mer kompakt och lĂ€sbart sĂ€tt, utöver de inbyggda funktionerna i API:et. Till exempel, som du kanske redan har lagt mĂ€rke till, nĂ€mndes inte metoden apply i den föregĂ„ende paragrafen. För nĂ€rvarande (maj 2020, översĂ€ttarens anm.) fungerar all logik kubectl apply, det vill sĂ€ga skapandet av icke-existerande resurser och uppdatering av befintliga, helt och hĂ„llet pĂ„ klientsidan kubectl. Insatser görs apply till API-sidan, men detta Ă€r fortfarande i beta-testning. Jag kommer att gĂ„ in mer detaljerat nedan.
Som standard anvÀnds Patch
BÀst att tillÀmpa patch, om du vill uppdatera en resurs. SÄ fungerar bÄde klientbiblioteken ovanpÄ Kubernetes API och kubectl (inte förvÄnande, eftersom det Àr en wrapper över klientbiblioteket, översÀttarens anm.).
Arbeta strategiskt
Alla kommandon kubectl apply, edit och patch anvÀnder metoden PATCH i HTTP-förfrÄgningar för att uppdatera en befintlig resurs. Om vi gÄr djupare in i implementeringen av kommandona, anvÀnds i alla fall metoden för att uppdatera resurser, Àven om kommandot patch kan anvÀnda andra metoder (mer om detta nedan). Metoden strategic-merge patching försöker 'göra allt rÀtt' nÀr den slÄr ihop den tillhandahÄllna specifikationen med den befintliga. Mer specifikt försöker den kombinera bÄde objekt och matriser, vilket betyder att Àndringar vanligtvis Àr additiva. Till exempel, om man kör kommandot patch med en ny miljövariabel i podens containerspecifikation, lÀggs denna miljövariabel till de befintliga miljövariablerna istÀllet för att ÄsidosÀtta dem. För att ta bort med denna metod bör parameterinstÀllningen tvingas till null i den tillhandahÄllna specifikationen. Vilka kommandon kubectl Àr bÀst att anvÀnda för uppdatering?
Om du skapar och hanterar dina resurser med kubectl apply, Àr det alltid bÀst att anvÀnda kubectl apply, sÄ att kubectl kan hantera konfigurationen och korrekt spÄra begÀrda Àndringar frÄn tillÀmpning till tillÀmpning. Fördelen med att alltid anvÀnda apply Àr att det spÄrar den tidigare tillÀmpade specifikationen, vilket gör att det vet nÀr specifikationens egenskaper och matrisens element uttryckligen tas bort. Detta möjliggör anvÀndning av apply för att ta bort egenskaper och element frÄn en array, medan vanlig strategisk sammanslagning inte fungerar. Kommandon edit och patch uppdaterar inte anteckningar som kubectl apply anvÀnds för att spÄra sina förÀndringar, sÄ eventuella förÀndringar som spÄras och görs genom API:et Kubernetes, men som görs via kommandon edit och patch, Àr osynliga för efterföljande kommandon apply, det vill sÀga apply tar inte bort dem, Àven om de inte visas i den ingÄende specifikationen för apply (I dokumentationen stÄr det att edit och patch gör uppdateringar av anteckningar som anvÀnds apply, men i praktiken gör de inte det).
Om du inte anvÀnder kommandot apply, kan du anvÀnda edit, sÄvÀl som patch, och vÀlja det kommando som passar bÀst för den förÀndring som görs. Vid tillÀgg och Àndring av egenskaper i specifikationen Àr de tvÄ metoderna i stort sett desamma. Vid borttagning av egenskaper i specifikationen eller element i en array edit bete sig som ett engÄngskörning apply, inklusive att spÄra vad specifikationen var före och efter redigeringen, sÄ att det Àr möjligt att explicit ta bort egenskaper och element frÄn arrayen frÄn resursen. Det Àr nödvÀndigt att explicit sÀtta vÀrdet för egenskapen till null i specifikationen för patch, för att ta bort den frÄn resursen. Att ta bort ett element i arrayen med hjÀlp av strategisk sammanslagningspatching Àr mer komplicerat, eftersom det krÀver anvÀndning av sammanslagningsdirektiv. Se andra tillvÀgagÄngssÀtt för uppdatering nedan för att vÀlja mer acceptabla alternativ.
För att implementera i klientbiblioteket metoder för uppdatering som beter sig pÄ liknande sÀtt som ovanstÄende kommandon kubectl, bör i begÀrningarna stÀllas in content-type pÄ application/strategic-merge-patch+json. Om du vill ta bort egenskaper i specifikationen behöver du uttryckligen sÀtta deras vÀrden till null pÄ samma sÀtt som kubectl patch. Om du behöver ta bort element frÄn arrayen, bör du inkludera sammanslagningsdirektiv i uppdateringsspecifikationen eller anvÀnda en annan metod för uppdateringar.
Andra tillvÀgagÄngssÀtt för uppdateringar
I Kubernetes stöds tvÄ andra tillvÀgagÄngssÀtt för uppdateringar: och . JSON merge patch-metoden tar emot en partiell specifikation av Kubernetes som indata och stödjer sammanslagning av objekt liknande metoden för strategic-merge patching. Skillnaden mellan dem Àr att den endast stödjer ersÀttning av arrayer, inklusive arrayen av containrar i pod-specifikationen. Det innebÀr att nÀr du anvÀnder JSON merge patch mÄste du tillhandahÄlla kompletta specifikationer för alla containrar om nÄgon egenskap hos en container Àndras. PÄ sÄ sÀtt Àr denna metod anvÀndbar för att ta bort element frÄn arrayen i specifikationen. I kommandoraden kan du vÀlja JSON merge patch med kubectl patch --type=merge. NÀr du arbetar med Kubernetes API bör du anvÀnda begÀran metod PATCH och stÀlla in content-type pÄ application/merge-patch+json.
JSON patch-metoden istÀllet för att tillhandahÄlla en partiell resurs-specifikation, anvÀnder en lista över Àndringar som du vill göra i resursen i form av en array, dÀr varje element i arrayen representerar en beskrivning av förÀndringen som görs i resursen. Denna metod Àr mer flexibel och kraftfull för att uttrycka de Àndringar som görs, men detta sker pÄ bekostnad av att listan av gjorda Àndringar Àr i ett separat format, inte Kubernetes, istÀllet för att skicka en partiell resurs-specifikation. I kubectl kan du vÀlja JSON patch med kubectl patch --type=json. NÀr du anvÀnder Kubernetes API fungerar denna metod med hjÀlp av begÀran metoden PATCH och stÀlla in content-type pÄ application/json-patch+json.
Behöver sĂ€kerhet â anvĂ€nd replace
I vissa fall behöver du vara sÀker pÄ att resursen inte kommer att Àndras mellan tiden för att lÀsa resursen och dess uppdatering. Med andra ord, se till att alla Àndringar blir atomÀra. I detta fall bör du anvÀnda replace. Till exempel, om det finns en ConfigMap med en rÀknare som uppdateras av flera kÀllor, bör du vara sÀker pÄ att tvÄ kÀllor inte uppdaterar rÀknaren samtidigt, vilket skulle leda till att uppdateringen gÄr förlorad. För att demonstrera, förestÀll dig en sekvens av hÀndelser dÀr patch:
- A och B fÄr den aktuella tillstÄndet av resursen frÄn API
- Var och en uppdaterar lokalt specifikationen, ökar rÀknaren med ett och lÀgger till "A" respektive "B" i noteringen "updated-by"
- A uppdaterar resursen nÄgot snabbare
- B uppdaterar resursen
Som ett resultat förlorades uppdatering A. Den senaste operationen patch vinner, rÀknaren ökar med ett istÀllet för tvÄ, och vÀrdet pÄ noteringen "updated-by" slutar med "B" och innehÄller inte "A". LÄt oss jÀmföra det ovanstÄende med vad som hÀnder nÀr uppdateringar görs med hjÀlp av tillvÀgagÄngssÀttet replace:
- A och B fÄr den aktuella tillstÄndet av resursen frÄn API
- Var och en uppdaterar lokalt specifikationen, ökar rÀknaren med ett och lÀgger till "A" respektive "B" i noteringen "updated-by"
- A uppdaterar resursen nÄgot snabbare
- B försöker uppdatera resurser, men uppdateringen avvisas av API:et eftersom versionen av resursen i specifikationen
replaceinte matchar den aktuella versionen av resursen i Kubernetes, eftersom resursversionen har ökat vid utförande av en ersÀttning frÄn A.
I det ovanstÄende fallet mÄste B hÀmta resurserna igen, göra Àndringar i det nya tillstÄndet och försöka igen replace. Som ett resultat kommer rÀknaren att öka med tvÄ, och noteringen "updated-by" kommer att innehÄlla "AB" i slutet.
Det ovanstĂ„ende exemplet antyder att vid utförande av replace en fullstĂ€ndig ersĂ€ttning av hela resurser utförs. Specifikationen som anvĂ€nds för replace, mĂ„ste vara fullstĂ€ndig och inte partiell, som i apply, utan fullstĂ€ndig, inklusive tillĂ€gg av resourceVersion till metadata i specifikationen. Om du inte inkluderade resourceVersion eller om den version du tillhandahöll inte Ă€r den aktuella, kommer ersĂ€ttningen att avvisas. DĂ€rför Ă€r det bĂ€sta tillvĂ€gagĂ„ngssĂ€ttet att anvĂ€nda replace â lĂ€sa resurser, uppdatera dem och omedelbart ersĂ€tta. Genom att anvĂ€nda kubectl, kan det se ut sĂ„ hĂ€r:
$ kubectl get deployment my-deployment -o json
| jq '.spec.template.spec.containers[0].env[1].value = "new value"'
| kubectl replace -f -Det Àr vÀrt att notera att de följande tvÄ kommandona, som körs sekventiellt, kommer att lyckas eftersom deployment.yaml inte innehÄller attributet .metadata.resourceVersion
$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yamlDet verkar som detta strider mot vad som nĂ€mndes ovan, det vill sĂ€ga "tillĂ€gg av resourceVersion i metadata i specifikationen". Ăr det felaktigt att hĂ€vda det? Nej, det Ă€r det inte, eftersom om kubectl upptĂ€cker att du inte angav resourceVersion, kommer den att lĂ€sa den frĂ„n resursen och lĂ€gga till den i den specifikation du angav och först dĂ€refter utföra replace. Eftersom denna potentiellt farliga, om man förlitar sig pĂ„ atomĂ€ritet, magi fungerar helt pĂ„ sidan av kubectl, ska man inte förlita sig pĂ„ den nĂ€r man anvĂ€nder klientbibliotek som arbetar med API:et. I det hĂ€r fallet kommer du att behöva lĂ€sa den aktuella specifikationen för resursen, uppdatera den och sedan utföra PUT begĂ€ran.
Man kan inte göra patch â vi gör replace
Ibland behöver man göra vissa Àndringar som inte kan hanteras av API:et. I dessa fall kan man tvinga fram att resurser byts ut genom att ta bort och Äterskapa dem. Detta görs med kubectl replace --force. Att köra kommandot tar omedelbart bort resurserna och Äterskaper dem med den angivna specifikationen. Det finns ingen hanterare för "tvinga fram byte" i API:et, och för att göra detta via API:et mÄste tvÄ operationer utföras. Först mÄste resurserna tas bort, och man sÀtter gracePeriodSeconds till noll (0) och propagationPolicy till "Background", och sedan Äterskapa denna resurs med den önskade specifikationen.
Observera: denna metod Àr potentiellt farlig och kan leda till ett osÀkert tillstÄnd.
Apply pÄ serversidan
Som nÀmnts ovan jobbar Kubernetes-utvecklarna pÄ att implementera logik apply frÄn kubectl i Kubernetes API:et. Logiken apply Àr tillgÀnglig i Kubernetes 1.18 via kubectl apply --server-side eller via API:et, med metoden PATCH med content-type application/apply-patch+YAML.
Observera: JSON Àr ocksÄ giltig YAML, sÄ man kan skicka specifikationen i JSON-format, Àven om
content-typeFör anvÀndare med migrÀn och epilepsi har vissa animations effekter vid öppning av flikar tagits bort. Till exempel, istÀllet för den hoppande punkten visas nu en ikon med sandur under tiden fliken laddar.application/apply-patch+yaml.
Dessutom, att logiken kubectl blir tillgÀnglig för alla via API:et, apply pÄ serversidan spÄrar den ansvariga för fÀlten i specifikationen, vilket möjliggör sÀker samtidig redigering utan konflikter. Med andra ord, om apply pÄ serversidan fÄr en bredare spridning, kommer det att finnas ett universellt sÀkerhetsgrÀnssnitt för hantering av resurser för olika klienter, som kubectl, Pulumi eller Terraform, GitOps, samt skrÀddarsydda skript som anvÀnder klientbibliotek.
Sammanfattning
Jag hoppas att denna korta översikt över olika sÀtt att uppdatera resurser i kluster var anvÀndbar för dig. Det Àr bra att veta att det inte bara Àr apply mot replace, eftersom man kan uppdatera en resurs med apply, edit, patch eller replace. Var och en har verkligen sitt eget tillÀmpningsomrÄde. För atomÀra förÀndringar Àr replace att föredra, annars bör man anvÀnda strategic-merge patch genom apply. I sista hand hoppas jag att du förstod att man inte kan lita pÄ Google eller StackOverflow nÀr man söker "kubernetes apply vs replace". à tminstone tills denna artikel ersÀtter det aktuella svaret.

KĂ€lla: habr.com
