Pareiza Kubernetes Apply, Replace un Patch salīdzināŔana

Kubernetes ir vairākas resursu atjaunināŔanas iespējas: apply, edit, patch un replace. Ir neskaidrÄ«bas par to, ko katra no tām dara un kad tās lietot. DarÄ«sim skaidru.

Pareiza Kubernetes Apply, Replace un Patch salīdzināŔana

Ja meklēt Google frāzi "kubernetes apply vs replace", atrodas atbilde StackOverflow, kas nav pareiza. Meklējot "kubernetes apply vs patch", pirmais links ir dokumentācija par kubectl patch, kas nesatur salÄ«dzinājumu apply un patch. Å ajā rakstā tiks izskatÄ«tas dažādas iespējas, kā arÄ« pareiza katras no tām izmantoÅ”ana.

Kubernetes resursa (servisa, deployment, ingress u.tml.) dzÄ«ves cikla laikā dažreiz ir nepiecieÅ”ams mainÄ«t, pievienot vai dzēst dažas Ŕī resursa Ä«paŔības. Piemēram, pievienot komentāru, palielināt vai samazināt replikāciju skaitu.

Kubernetes CLI

Ja jÅ«s jau strādājat ar Kubernetes klasteriem caur CLI, tad esat jau iepazinies ar apply un edit. Komanda apply specifikāciju lasa no faila un veic "upsert" Kubernetes klasterÄ«, t.i., izveido resursu, ja tā nav, un atjaunina to, ja tas pastāv. Komanda edit resursu lasa caur API, pēc tam raksta resursa specifikāciju lokālā failā, kuru pēc tam atver tekstu redaktorā. Kad jÅ«s to rediģēsit un saglabāsit failu, kubectl nosÅ«tÄ«s veiktās izmaiņas atpakaļ caur API, kas uzmanÄ«gi attiecina Ŕīs izmaiņas uz resursu.

Ne visi zina komandas patch un replace. Komanda patch ļauj mainÄ«t resursa specifikācijas daļu, norādot tikai mainÄ«to daļu komandrindā. Komanda replace strādā tāpat kā edit, bet viss jādara manuāli: ir jāleij current-specification versija, piemēram, ar kubectl get -o yaml, jārediģē tas, pēc tam jādara replace resursa atjaunināŔanai saskaņā ar mainÄ«to specifikāciju. Komanda replace nestrādās, ja starp lasīŔanu un resursa apmaiņu notiks kādas izmaiņas.

Kubernetes API

JÅ«s, iespējams, esat pazÄ«stams ar metodēm CoreV1().Pods().Update(), replaceNamespacedService vai patch_namespaced_deployment, ja strādājat ar klasteriem caur klietu bibliotēku Kubernetes API izmantojot noteiktu programmēŔanas valodu. Bibliotēka apstrādā Ŕīs metodes ar HTTP pieprasÄ«jumiem, izmantojot metodes PUT un PATCH. Tajā paŔā laikā update un replace izmanto PUT, bet patch, kā tas varētu bÅ«t banāli, izmanto PATCH.

JāatzÄ«mē, ka kubectl arÄ« strādā ar klasteriem caur API. Citiem vārdiem sakot, kubectl– ir apvalks virs klienta bibliotēkas Go valodai, kas bÅ«tÄ«bā nodroÅ”ina iespēju sniegt apakÅ”komandas kompaktākā un viegli lasāmā formā papildus standarta API iespējām. Piemēram, kā jÅ«s jau varējāt ievērot, metode apply netika minēta iepriekŔējā teikumā. PaÅ”laik (2020. gada maijs, piezÄ«me tulkotājam) visa loÄ£ika kubectl apply, t.i., jaunu resursu izveide un esoÅ”o atjaunināŔana, darbojas pilnÄ«bā koda pusē kubectl. Tiek veikti centieni pārnest loÄ£iku apply uz API pusi, bet tas joprojām ir beta testēŔanas fāzē. SÄ«kāk izskaidroÅ”u turpmāk.

Patch pēc noklusējuma

Vislabāk ir piemērot patch, ja vēlaties atjaunināt resursu. Tā darbojas gan klienta bibliotēkas virs API Kubernetes, gan arī kubectl (nav pārsteigums, jo tas ir klienta bibliotēkas apvalks, piezīme tulkotājam).

Darboties stratēģiski

Visas komandas kubectl apply, edit un patch izmanto metodi PATCH HTTP pieprasÄ«jumos esoŔā resursa atjaunināŔanai. Ja iedziļināmies komandu Ä«stenoÅ”anā, tad visās tiek izmantots pieejas strategic-merge patching resursu atjaunināŔanai, lai gan komanda patch var izmantot arÄ« citas pieejas (sÄ«kāk par to zemāk). Pieeja strategic-merge patching cenÅ”as 'izdarÄ«t visu pareizi', apvienojot sniegto specifikāciju ar esoÅ”o specifikāciju. Vairāk konkrēti, tā cenÅ”as apvienot gan objektus, gan masÄ«vus, kas nozÄ«mē, ka izmaiņas parasti ir aditÄ«vas. Piemēram, komandas izpilde patch ar jaunu vides mainÄ«go konteineru pod specifikācijā, noved pie tā, ka Å”is vides mainÄ«gais tiek pievienots esoÅ”ajiem vides mainÄ«gajiem, nevis tos pārraksta. Lai dzēstu, izmantojot Å”o pieeju, vajadzētu piespiest parametra vērtÄ«bu iestatÄ«t uz null, sniegtajā specifikācijā. Kuri no komandām kubectl ir vislabāk lietot atjaunināŔanai?

Ja jÅ«s izveidojat un pārvaldāt savus resursus, izmantojot kubectl apply, atjaunojot vienmēr labāk izmantot kubectl apply, lai kubectl varētu pārvaldÄ«t konfigurāciju un pareizi sekot pieprasÄ«tajām izmaiņām no lietoÅ”anas uz lietoÅ”anu. PriekÅ”rocÄ«ba vienmēr izmantot apply ir tā, ka tas seko iepriekŔējo specifikāciju, ļaujot tam zināt, kad specifikācijas Ä«paŔības un masÄ«va elementi ir skaidri dzēsti. Tas ļauj izmantot apply lai izdzēstu Ä«paŔības un masÄ«vu elementus, kamēr parastā stratēģiskā apvienoÅ”ana nedarbosies. Komandas edit un patch neatjauno piezÄ«mes, kuras kubectl apply tiek izmantotas, lai sekotu lÄ«dz izmaiņām, tāpēc visas izmaiņas, kas tiek uzskaitÄ«tas un veiktas caur Kubernetes API, bet izdarÄ«tas, izmantojot komandas edit un patch, ir neredzamas turpmākajām komandām apply, proti, apply neizdzēŔ tās, pat ja tās neparādās ieveidoto specifikācijā apply (Dokumentācijā teikts, ka edit un patch veic piezÄ«mju atjauninājumus, kas izmantoti apply, bet praksē – nē).

Ja jÅ«s neizmantojat komandu apply, var izmantot kā edit, gan patch, izvēloties to komandu, kas vislabāk atbilst veiktajai izmaiņai. Pievienojot un mainot specifikācijas Ä«paŔības, abi piekļuve ir aptuveni vienādi. Izslēdzot specifikācijas Ä«paŔības vai masÄ«va elementus edit uzvedas kā vienreizēja palaiÅ”ana apply, tajā skaitā seko, kāda bija specifikācija pirms un pēc rediģēŔanas, tāpēc var skaidri izdzēst Ä«paŔības un masÄ«vu elementus no resursa. Ir skaidri jānosaka Ä«paŔības vērtÄ«ba kā nullē specifikācijā patch, lai izdzēstu to no resursa. MasÄ«va elementa izdzēŔana, izmantojot stratēģisku apvienoÅ”anas pieeju, ir sarežģītāka, jo nepiecieÅ”ams izmantot apvienoÅ”anas direktÄ«vas. Skatiet citas pieejas atjaunināŔanai zemāk, lai izvēlētos piemērotākas alternatÄ«vas.

Lai klienta bibliotēkā Ä«stenotu atjauninājuma metodes, kas uzvedas lÄ«dzÄ«gi iepriekÅ” minētajām komandām kubectl, jāizvirza content-type par application/strategic-merge-patch+json. Ja vēlaties izdzēst Ä«paŔības specifikācijā, ir skaidri jānosaka to vērtÄ«bas kā nullē lÄ«dzÄ«gi kubectl patch. Ja ir nepiecieÅ”ams izdzēst masÄ«va elementus, jums jāiekļauj apvienoÅ”anas direktÄ«vas atjaunināŔanas specifikācijā vai jāizmanto cita pieeja atjauninājumiem.

Citas pieejas atjauninājumiem

Kubernetes atbalsta divas citas pieejas atjaunināŔanai: JSON apvienoÅ”anas plāksteris un JSON plāksteris. JSON merge patch pieņem daļēju Kubernetes specifikāciju kā ievadi un atbalsta objektu apvienoÅ”anu, lÄ«dzÄ«gi kā pieeja strategic-merge patching. AtŔķirÄ«ba starp tām ir tāda, ka tā atbalsta tikai masÄ«vu nomaiņu, tostarp konteineru masÄ«vu pod specifikācijā. Tas nozÄ«mē, ka, izmantojot JSON merge patch, jums jāsniedz pilnas specifikācijas visiem konteineriem gadÄ«jumā, ja ir izmaiņas kādā no konteineru Ä«paŔībām. Tādējādi Ŕī pieeja ir noderÄ«ga, lai noņemtu elementus no masÄ«va specifikācijā. Komandu rindā jÅ«s varat izvēlēties JSON merge patch, izmantojot kubectl patch --type=merge. Strādājot ar Kubernetes API, jāizmanto pieprasÄ«juma metode PATCH un iestatīŔana content-type par application/merge-patch+json.

JSON patch pieeja, nevis sniedzot daļēju resursa specifikāciju, izmanto izmaiņu sniegÅ”anu, kuras vēlaties veikt resursā, kā masÄ«vu, kur katrs masÄ«va elements attēlo izmaiņas, ko veicat resursā. Å Ä« pieeja ir elastÄ«gāka un jaudÄ«gāka izmaiņu izteikÅ”anas metode, taču atspoguļo to, ka izmaiņu saraksts ir atseviŔķā, Kubernetes nesaskanÄ«gā formātā, nevis sÅ«tot daļēju resursa specifikāciju. JÅ«s kubectl varat izvēlēties JSON patch, izmantojot kubectl patch --type=json. Izmantojot Kubernetes API, Ŕī pieeja darbojas, izmantojot pieprasÄ«juma metodi PATCH un iestatīŔana content-type par application/json-patch+json.

NepiecieÅ”ama pārliecÄ«ba — izmantojam replace

Dažreiz ir nepiecieÅ”ama pārliecÄ«ba, ka resursā netiks veiktas izmaiņas starp laiku, kad tiek lasÄ«ts resurss, un tā atjaunināŔanu. Citiem vārdiem sakot, jābÅ«t droÅ”iem, ka visas izmaiņas bÅ«s atomāras. Šādā gadÄ«jumā resursu atjaunināŔanai labāk izmantot replace. Piemēram, ja ir ConfigMap ar skaitÄ«tāju, kuru atjaunina vairāki avoti, jābÅ«t pārliecinātiem, ka divi avoti vienlaikus neatsvaidzinās skaitÄ«tāju, kas var novest pie atjauninājuma zuduma. Lai ilustrētu, iedomājieties scenāriju, izmantojot pieeju patch:

  • A un B iegÅ«st paÅ”reizējo resursa stāvokli no API
  • Katrs no viņiem lokāli atjaunina specifikāciju, palielinot skaitÄ«tāju par vienu, kā arÄ« pievienojot "A" vai "B", attiecÄ«gi, pie piezÄ«mes "updated-by"
  • A nedaudz ātrāk atjaunina resursu
  • B atjaunina resursu

Kā rezultātā A atjauninājums ir zaudēts. Pēdējā operācija patch uzvar, skaitÄ«tājs palielinās par vienu, nevis diviem, un piezÄ«mes "updated-by" vērtÄ«ba beidzas ar "B" un nesatur "A". SalÄ«dzināsim iepriekÅ” minēto ar to, kas notiek, kad atjauninājumi tiek veikti izmantojot pieeju replace:

  • A un B iegÅ«st paÅ”reizējo resursa stāvokli no API
  • Katrs no viņiem lokāli atjaunina specifikāciju, palielinot skaitÄ«tāju par vienu, kā arÄ« pievienojot "A" vai "B", attiecÄ«gi, pie piezÄ«mes "updated-by"
  • A nedaudz ātrāk atjaunina resursu
  • B mēģina atjaunināt resursu, taču API noraida atjauninājumu, jo resursa versija specifikācijā replace nesakrÄ«t ar paÅ”reizējo resursa versiju Kubernetes, jo resursa versija tika palielināta, veicot aizvietoÅ”anas operāciju no A puses.

IepriekÅ” minētajā gadÄ«jumā B bÅ«s jāiegÅ«st resurss no jauna, jāveic izmaiņas jaunajā stāvoklÄ« un jāmēģina vēlreiz replace. Rezultātā skaitÄ«tājs tiks palielināts par diviem, un piezÄ«me "updated-by" beigsies ar "AB".

IepriekÅ” minētais piemērs norāda, ka, veicot replace tiek veikta pilnÄ«ga visu resursu aizvietoÅ”ana. Specifikācija, kas tiek izmantota replace, jābÅ«t nevis daļējai, vai daļām kā apply, bet pilnai, iekļaujot pievienoÅ”anas resourceVersion metadatu specifikācijā. Ja jÅ«s neiekļāvāt resourceVersion vai sniegtā versija nav paÅ”reizējā, aizvietoÅ”ana tiks noraidÄ«ta. Tādējādi labākā pieeja izmantoÅ”anai replace ir izlasÄ«t resursu, atjaunināt to un nekavējoties aizvietot. Izmantojot kubectl, tas var izskatÄ«ties Ŕādi:

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

Vērts atzÄ«mēt, ka nākamās divas komandas, kas izpildÄ«tas secÄ«gi, izpildÄ«sies veiksmÄ«gi, jo deployment.yaml nesatur Ä«paÅ”umu .metadata.resourceVersion

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

Izskatās, ka tas ir pretrunā ar to, kas tika teikts iepriekÅ”, proti, "pievienojot resourceVersion metadatiem specifikācijā". Apgalvot tā ir nepareizi? Nē, tā nav, jo, ja kubectl pamanÄ«s, ka jÅ«s neesat norādÄ«jis resourceVersion, tas izlasÄ«s to no resursa un pievienos norādÄ«tajai specifikācijai un tikai tad izpildÄ«s replace. Ņemot vērā, ka tas potenciāli ir bÄ«stami, ja paļaujas uz atomaritāti, Ŕī burvÄ«ba strādā pilnÄ«bā no kubectl, nevajadzētu uz to paļauties, lietojot klientu bibliotēkas, kas strādā ar API. Å ajā gadÄ«jumā jums bÅ«s jāizlasa paÅ”reizējā resursa specifikācija, jāatjaunina tā un pēc tam jāveic PUT pieprasÄ«jums.

Nav iespējams veikt patch – mēs veicam replace

Dažreiz ir nepiecieÅ”ami izmaiņas, kuras nevar apstrādāt API. Šādos gadÄ«jumos var piespiedu kārtā aizstāt resursus, tos izdzēŔot un atkal izveidojot. To var izdarÄ«t ar kubectl replace --force. Komandas izpilde nekavējoties izdzēŔ resursus un pēc tam tos izveido no sniegtās specifikācijas. API nav "piespiedu aizstāŔanas" apstrādātāja, un, lai to izdarÄ«tu caur API, ir jāveic divas darbÄ«bas. Vispirms jādara izdzēst resurss, iestatot tam gracePeriodSeconds uz nulli (0) un propagationPolicy uz ā€œBackgroundā€, un pēc tam atkal jāizveido Å”is resurss ar vēlamo specifikāciju.

Brīdinājums: Ŕī pieeja potenciāli ir bīstama, var novest pie nenoteikta stāvokļa

Apply servera pusē

Kā jau minēts iepriekÅ”, Kubernetes izstrādātāji strādā pie loÄ£ikas Ä«stenoÅ”anas apply no kubectl Kubernetes API. LoÄ£ika apply ir pieejama Kubernetes 1.18 versijā, izmantojot kubectl apply --server-side vai caur API, izmantojot metodi PATCH ar content-type application/apply-patch+YAML.

Piezīme: JSON arī ir derīgs YAML, tāpēc specifikāciju var nosūtīt JSON formātā, pat ja content-type tiks application/apply-patch+yaml.

Turklāt, loÄ£ika kubectl ir pieejama visiem caur API, apply servera pusē uzrauga atbildÄ«gos par specifikācijas laukiem, tādējādi ļaujot droÅ”u vairāku piekļuvi tās konfliktu bezredaktēŔanai. Citiem vārdiem sakot, ja apply servera pusē tiks iegÅ«ti plaŔāki izplatÄ«jumi, parādÄ«sies universāla droÅ”a resursu pārvaldÄ«bas saskarne dažādiem klientiem, piemēram, kubectl, Pulumi vai Terraform, GitOps, kā arÄ« pielāgotiem skriptiem, kas izmanto klientu bibliotēkas.

Secinājumi

Ceru, ka Å”is Ä«sais pārskats par dažādajiem veidiem, kā atjaunināt resursus klasteros, bija noderÄ«gs jums. Ir noderÄ«gi zināt, ka nav tikai ā€œapplyā€ pret ā€œreplaceā€, jo resursu var atjaunināt, izmantojot apply, edit, patch vai replace. Galu galā katra pieeja ir piemērota savai lietoÅ”anai. Atomārām izmaiņām labāk izmantot replace, pretējā gadÄ«jumā ir jāizmanto strategic-merge patch, izmantojot apply. Visbeidzot, es ceru, ka jÅ«s sapratāt, ka nevajadzētu paļauties uz Google vai StackOverflow, meklējot "kubernetes apply vs replace". Vismaz lÄ«dz brÄ«dim, kad Å”is raksts aizstās paÅ”reizējo atbildi.

Pareiza Kubernetes Apply, Replace un Patch salīdzināŔana

Avots: habr.com

Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem šŸ”„ Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem | ProHoster