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.
Ak 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 PUT
и PATCH
... Čím update
и replace
použitý PUT
A 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, kubectl
je 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 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 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 apply
na 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 apply
To 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 edit
A 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 patch
na 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: 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ôleapplication/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ď.
Zdroj: hab.com