Správne porovnanie aplikácií Kubernetes, výmeny a opravy

Kubernetes má niekoľko možností aktualizácie zdrojov: použiť, upraviť, opraviť a nahradiť. Existuje zmätok v tom, čo každý z nich robí a kedy ich použiť. Poďme na to.

Správne porovnanie aplikácií Kubernetes, výmeny a opravy

Ak hľadať na Google nachádza sa fráza „použiť kubernetes vs nahradiť“. odpovedať na StackOverflow, čo nie je správne. Pri hľadaní "kubernetes apply vs patch" prvý odkaz je dokumentácia kubectl patch, ktorá nezahŕňa porovnanie apply и patch. Tento článok sa bude zaoberať rôznymi možnosťami, ako aj správnym použitím každej z nich.

Počas životného cyklu zdroja Kubernetes (služba, nasadenie, vstup atď.) niekedy potrebujete zmeniť, pridať alebo odstrániť niektoré vlastnosti tohto prostriedku. Napríklad pridajte poznámku, zvýšte alebo znížte počet replík.

Kubernetes CLI

Ak už pracujete s klastrami Kubernetes cez CLI, už ste oboznámení apply и edit. Tím apply prečíta špecifikáciu prostriedku zo súboru a urobí „upsert“ do klastra Kubernetes, t.j. vytvorí zdroj, ak neexistuje, a aktualizuje ho, ak existuje. Tím edit načíta zdroj cez API, potom zapíše špecifikáciu zdroja do lokálneho súboru, ktorý sa potom otvorí v textovom editore. Po úprave a uložení súboru kubectl odošle vykonané zmeny späť cez rozhranie API, ktoré tieto zmeny starostlivo aplikuje na zdroj.

Nie každý pozná príkazy patch и replace. Tím patch umožňuje zmeniť časť špecifikácie prostriedku, pričom na príkazovom riadku poskytuje iba zmenenú časť. Tím replace funguje rovnako ako edit, ale všetko je potrebné urobiť ručne: musíte si stiahnuť aktuálnu verziu špecifikácie zdroja, napríklad pomocou kubectl get -o yaml, upravte ho a potom použite replace aktualizovať zdroj podľa zmenenej špecifikácie. Tím replace nebude fungovať, ak medzi čítaním a výmenou zdroja nastanú nejaké zmeny.

Kubernetes API

Pravdepodobne ste oboznámení s metódami CoreV1().Pods().Update(), replaceNamespacedService alebo patch_namespaced_deployment, ak pracujete s klastrami cez klientska knižnica pre Kubernetes API pomocou nejakého programovacieho jazyka. Knižnica spracováva tieto metódy prostredníctvom HTTP požiadaviek pomocou metód PUT и PATCH... Čím update и replace použitý PUTA patch, bez ohľadu na to, aké triviálne to môže byť, používa PATCH.

Je potrebné poznamenať, že kubectl pracuje aj s klastrami cez API. Inými slovami, kubectlje obal na vrchu klientskej knižnice pre jazyk Go, ktorý do značnej miery poskytuje možnosť poskytovať čiastkové príkazy v kompaktnejšej a čitateľnejšej forme okrem štandardných schopností API. Napríklad, ako ste si už mohli všimnúť, metóda apply nebolo uvedené vyššie v predchádzajúcom odseku. Aktuálne (máj 2020, približne. prekladateľ) celá logika kubectl apply, t.j. vytváranie neexistujúcich zdrojov a aktualizácia existujúcich, funguje výlučne na strane kódu kubectl. Vyvíja sa úsilie na logický prenos apply na stranu API, ale stále je v beta verzii. Podrobnejšie napíšem nižšie.

Oprava v predvolenom nastavení

Najlepšie používané patch, ak chcete aktualizovať zdroj. Takto fungujú obe klientske knižnice nad rozhraním Kubernetes API a kubectl (Nie je prekvapujúce, pretože ide o obal pre knižnicu klienta, približne. prekladateľ).

Pracujte strategicky

Všetky tímy kubectl apply, edit и patch použiť metódu PATCH v požiadavkách HTTP na aktualizáciu existujúceho zdroja. Ak sa podrobnejšie ponoríte do implementácie príkazov, potom všetky používajú tento prístup záplatovanie strategického zlúčenia aktualizovať zdroje, hoci príkaz patch môže použiť iné prístupy (viac o tom nižšie). Prístup opráv strategického zlúčenia sa pokúša „dostať do poriadku“ zlúčením dodanej špecifikácie s existujúcou špecifikáciou. Presnejšie povedané, snaží sa kombinovať objekty aj polia, čo znamená, že zmeny majú tendenciu byť aditívne. Napríklad spustenie príkazu patch s novou premennou prostredia v špecifikácii kontajnera pod spôsobí, že sa táto premenná prostredia pridá k existujúcim premenným prostredia, a nie ich prepíše. Ak chcete odstrániť pomocou tohto prístupu, musíte vynútiť hodnotu parametra null v poskytnutej špecifikácii. Ktorý z tímov kubectl Je najlepšie použiť na aktualizáciu?

Ak vytvárate a spravujete svoje zdroje pomocou kubectl apply, pri aktualizácii je lepšie vždy použiť kubectl applyna kubectl mohol spravovať konfiguráciu a správne sledovať požadované zmeny z aplikácie do aplikácie. Vždy používajte výhodu apply spočíva v tom, že sleduje predtým aplikovanú špecifikáciu, čo jej umožňuje vedieť, kedy sú vlastnosti špecifikácie a prvky poľa explicitne odstránené. To vám umožňuje používať apply na odstránenie vlastností a prvkov poľa, zatiaľ čo bežné strategické zlúčenie nebude fungovať. Tímy edit и patch neaktualizujte poznámky, že kubectl apply používa na sledovanie svojich zmien, takže všetky zmeny, ktoré sú sledované a vykonávané prostredníctvom rozhrania Kubernetes API, ale vykonávané prostredníctvom príkazov edit и patch, neviditeľné pre nasledujúce príkazy applyTo znamená, že apply neodstráni ich, aj keď sa neobjavia vo vstupnej špecifikácii pre apply (Dokumentácia hovorí, že edit и patch aktualizovať použité poznámky apply, ale v praxi - nie).

Ak nepoužijete príkaz apply, možno použiť ako editA patch, výberom príkazu, ktorý najlepšie vyhovuje vykonávanej zmene. Pri pridávaní a zmene vlastností kusovníka sú oba prístupy približne rovnaké. Pri odstraňovaní vlastností špecifikácie alebo prvkov poľa edit sa správa ako jednorazové spustenie apply, vrátane sledovania toho, aká bola špecifikácia pred a po úprave, takže môžete explicitne odstrániť vlastnosti a prvky poľa zo zdroja. Musíte explicitne nastaviť hodnotu vlastnosti na null v špecifikácii pre patchna jeho odstránenie zo zdroja. Odstránenie prvku poľa pomocou záplatovania strategického zlúčenia je zložitejšie, pretože vyžaduje použitie direktív zlučovania. Pozrite si ďalšie prístupy k inovácii nižšie, kde nájdete životaschopnejšie alternatívy.

Implementovať metódy aktualizácie v knižnici klienta, ktoré sa správajú podobne ako vyššie uvedené príkazy kubectl, treba nastaviť v žiadostiach content-type в application/strategic-merge-patch+json. Ak chcete odstrániť vlastnosti v špecifikácii, musíte podobným spôsobom explicitne nastaviť ich hodnoty na null kubectl patch. Ak potrebujete odstrániť prvky poľa, mali by ste do špecifikácie aktualizácie zahrnúť direktívy zlúčenia alebo použiť iný prístup k aktualizáciám.

Iné prístupy k aktualizáciám

Kubernetes podporuje dva ďalšie prístupy k aktualizácii: Oprava na zlúčenie JSON и JSON patch. Prístup záplaty zlúčenia JSON berie ako vstup čiastočnú špecifikáciu Kubernetes a podporuje zlučovanie objektov podobný prístupu záplatovania strategického zlúčenia. Rozdiel medzi nimi je v tom, že podporuje iba výmenu poľa vrátane poľa kontajnerov v špecifikácii modulu. To znamená, že pri použití záplaty na zlúčenie JSON musíte poskytnúť úplné špecifikácie pre všetky kontajnery v prípade, že sa zmení akákoľvek vlastnosť akéhokoľvek kontajnera. Takže tento prístup je užitočný na odstránenie prvkov z poľa v kusovníku. Na príkazovom riadku môžete vybrať opravu zlúčenia JSON pomocou kubectl patch --type=merge. Pri práci s Kubernetes API by ste mali použiť metódu žiadosti PATCH a inštaláciu content-type в application/merge-patch+json.

Prístup opravy JSON namiesto poskytovania čiastočnej špecifikácie zdroja používa poskytovanie zmien, ktoré chcete vykonať v zdroji, ako pole, v ktorom každý prvok poľa predstavuje popis zmeny, ktorá sa vykoná v prostriedku. Tento prístup predstavuje flexibilnejší a výkonnejší spôsob vyjadrenia vykonávaných zmien, ale za cenu uvedenia vykonaných zmien v samostatnom formáte, ktorý nepochádza z Kubernetes, namiesto odoslania čiastočnej špecifikácie zdroja. IN kubectl môžete vybrať opravu JSON pomocou kubectl patch --type=json. Pri použití Kubernetes API tento prístup funguje pomocou metódy požiadavky PATCH a inštaláciu content-type в application/json-patch+json.

Potrebujeme dôveru - použite náhradu

V niektorých prípadoch si musíte byť istí, že medzi prečítaním zdroja a jeho aktualizáciou sa v prostriedku nevykonajú žiadne zmeny. Inými slovami, mali by ste sa uistiť, že všetky zmeny budú atómový. V tomto prípade by ste mali použiť na aktualizáciu zdrojov replace. Napríklad, ak máte ConfigMap s počítadlom, ktoré je aktualizované z viacerých zdrojov, mali by ste si byť istí, že dva zdroje neaktualizujú počítadlo súčasne, čo spôsobí stratu aktualizácie. Na demonštráciu si predstavte postupnosť udalostí pomocou tohto prístupu patch:

  • A a B získajú aktuálny stav zdroja z API
  • Každý z nich lokálne aktualizuje špecifikáciu zvýšením počítadla o jednu a tiež pridaním „A“ alebo „B“ do poznámky „aktualizoval“.
  • A aktualizuje zdroj o niečo rýchlejšie
  • B aktualizuje zdroj

V dôsledku toho sa aktualizácia A stratí. Posledná operácia patch vyhráva, počítadlo sa zvýši o jednotku namiesto dvoch a hodnota poznámky „updated-by“ končí na „B“ a neobsahuje „A“. Porovnajme vyššie uvedené s tým, čo sa stane, keď sa aktualizácie vykonajú pomocou tohto prístupu replace:

  • A a B získajú aktuálny stav zdroja z API
  • Každý z nich lokálne aktualizuje špecifikáciu zvýšením počítadla o jednu a tiež pridaním „A“ alebo „B“ do poznámky „aktualizoval“.
  • A aktualizuje zdroj o niečo rýchlejšie
  • B sa pokúsi aktualizovať zdroj, ale aktualizácia je odmietnutá API, pretože verzia zdroja je v špecifikácii replace sa nezhoduje s aktuálnou verziou prostriedku v Kubernetes, pretože verzia prostriedku bola zvýšená operáciou nahradenia A.

Vo vyššie uvedenom prípade bude B musieť znova načítať zdroj, vykonať zmeny v novom stave a skúsiť to znova replace. To spôsobí, že počítadlo sa zvýši o dve a poznámka „updated-by“ bude obsahovať „AB“ na konci.

Vyššie uvedený príklad naznačuje, že pri vykonávaní replace Celý zdroj je úplne nahradený. Špecifikácia použitá pre replace, nesmie byť čiastočné, alebo po častiach ako v apply, ale komplet, vrátane dodatku resourceVersion do metadát špecifikácie. Ak ste to nepovolili resourceVersion alebo verzia, ktorú poskytnete, nie je aktuálna, náhrada bude zamietnutá. Takže najlepší spôsob použitia je replace – prečítajte si zdroj, aktualizujte ho a okamžite vymeňte. Použitím kubectl, môže to vyzerať takto:

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

Stojí za zmienku, že nasledujúce dva príkazy, vykonávané postupne, sa úspešne vykonajú od r deployment.yaml neobsahuje majetok .metadata.resourceVersion

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

Zdá sa, že to odporuje tomu, čo bolo povedané vyššie, t.j. "pridanie resourceVersion do metadát špecifikácie." Je nesprávne to povedať? Nie, nie je, pretože ak kubectl oznámenia, ktoré ste nešpecifikovali resourceVersion, načíta ho zo zdroja a pridá ho k špecifikácii, ktorú ste zadali, a až potom ho spustí replace. Pretože je to potenciálne nebezpečné, ak sa spoliehate na atomicitu, mágia funguje úplne bokom kubectl, nemali by ste sa naň spoliehať pri používaní klientskych knižníc, ktoré pracujú s API. V tomto prípade si budete musieť prečítať aktuálnu špecifikáciu zdroja, aktualizovať ju a potom spustiť PUT žiadosť.

Nemôžete urobiť opravu – my urobíme výmenu

Niekedy je potrebné vykonať zmeny, ktoré API nedokáže spracovať. V týchto prípadoch môžete vynútiť nahradenie prostriedku jeho odstránením a opätovným vytvorením. To sa robí pomocou kubectl replace --force. Spustenie príkazu okamžite odstráni prostriedky a potom ich znova vytvorí z dodanej špecifikácie. V rozhraní API nie je žiadny obslužný program „vynútiť nahradenie“ a aby ste to mohli urobiť prostredníctvom rozhrania API, musíte vykonať dve operácie. Najprv musíte odstrániť zdroj nastavením gracePeriodSeconds na nulu (0) a propagationPolicy v časti „Pozadie“ a potom znova vytvorte tento zdroj s požadovanou špecifikáciou.

Upozornenie: Tento prístup je potenciálne nebezpečný a môže viesť k nedefinovanému stavu.

Použiť na strane servera

Ako je uvedené vyššie, vývojári Kubernetes pracujú na implementácii logiky apply z kubectl v Kubernetes API. Logika apply dostupné v Kubernetes 1.18 cez kubectl apply --server-side alebo cez API pomocou metódy PATCH с content-type application/apply-patch+YAML.

Poznámka: JSON je tiež platný YAML, takže špecifikáciu môžete odoslať ako JSON, aj keď content-type vôle application/apply-patch+yaml.

Okrem tej logiky kubectl bude k dispozícii všetkým prostredníctvom API, apply na strane servera sleduje, kto je zodpovedný za polia v špecifikácii, čím umožňuje bezpečný viacnásobný prístup pre jej bezkonfliktnú úpravu. Inými slovami, ak apply na strane servera sa rozšíri, objaví sa univerzálne zabezpečené rozhranie na správu zdrojov pre rôznych klientov, napríklad kubectl, Pulumi alebo Terraform, GitOps, ako aj skripty písané vlastnými rukami pomocou klientskych knižníc.

Výsledky

Dúfam, že tento krátky prehľad rôznych spôsobov aktualizácie zdrojov v klastroch bol pre vás užitočný. Je dobré vedieť, že to nie je len použiť verzus nahradiť; je možné aktualizovať zdroj pomocou použitia, úpravy, opravy alebo nahradenia. Koniec koncov, v zásade má každý prístup svoju vlastnú oblasť použitia. Pre atómové zmeny je vhodnejšie nahradiť, inak by ste mali použiť opravu strategického zlúčenia prostredníctvom aplikácie. Prinajmenšom očakávam, že pochopíte, že nemôžete dôverovať Googlu ani StackOerflow pri hľadaní „kubernetes použiť vs nahradiť“. Aspoň dovtedy, kým tento článok nenahradí aktuálnu odpoveď.

Správne porovnanie aplikácií Kubernetes, výmeny a opravy

Zdroj: hab.com

Pridať komentár