Sondy živosti v Kubernetes môžu byť nebezpečné

Poznámka. preklad.: Hlavný inžinier zo Zalanda, Henning Jacobs, si medzi používateľmi Kubernetes opakovane všimol problémy s pochopením účelu sond živosti (a pripravenosti) a ich správnym používaním. Preto zhromaždil svoje myšlienky v tejto priestrannej poznámke, ktorá sa nakoniec stane súčasťou dokumentácie K8s.

Sondy živosti v Kubernetes môžu byť nebezpečné

Zdravotné kontroly, známe v Kubernetes ako sondy živosti (t. j. doslova „testy životaschopnosti“ - približne preklad.), môže byť dosť nebezpečné. Odporúčam sa im vyhnúť, ak je to možné: výnimkou sú prípady, keď sú skutočne nevyhnutné a vy si plne uvedomujete špecifiká a dôsledky ich používania. Táto publikácia bude hovoriť o kontrolách životaschopnosti a pripravenosti a tiež vám povie, v akých prípadoch je a nemali by ste ich používať.

Môj kolega Sandor nedávno zdieľal na Twitteri najčastejšie chyby, s ktorými sa stretáva, vrátane tých, ktoré súvisia s používaním sond pripravenosti/živosti:

Sondy živosti v Kubernetes môžu byť nebezpečné

Nesprávne nakonfigurované livenessProbe môže zhoršiť situácie s vysokým zaťažením (vypnutie snehovej gule + potenciálne dlhý čas spustenia kontajnera/aplikácie) a viesť k ďalším negatívnym dôsledkom, ako je pokles závislosti (pozri tiež môj nedávny článok o obmedzení počtu požiadaviek v kombinácii K3s+ACME). Je to ešte horšie, keď je sonda živosti kombinovaná so zdravotnou kontrolou, čo je externá databáza: jediné zlyhanie DB reštartuje všetky vaše kontajnery!

Všeobecná správa "Nepoužívajte sondy živosti" v tomto prípade to veľmi nepomôže, tak sa pozrime, na čo slúžia kontroly pripravenosti a životnosti.

Poznámka: Väčšina nižšie uvedeného testu bola pôvodne zahrnutá v internej vývojárskej dokumentácii Zalanda.

Kontroly pripravenosti a živosti

Kubernetes poskytuje dva dôležité mechanizmy tzv sondy živosti a sondy pripravenosti. Pravidelne vykonávajú nejakú akciu, ako je odoslanie požiadavky HTTP, otvorenie pripojenia TCP alebo vykonanie príkazu v kontajneri, aby potvrdili, že aplikácia funguje podľa očakávania.

Používa Kubernetes sondy pripravenostiaby ste pochopili, kedy je kontajner pripravený prijať premávku. Struk sa považuje za pripravený na použitie, ak sú pripravené všetky jeho nádoby. Jedným z použití tohto mechanizmu je ovládanie, ktoré moduly sa používajú ako backendy pre služby Kubernetes (a najmä Ingress).

Sondy živosti pomôcť Kubernetes pochopiť, kedy je čas reštartovať kontajner. Takáto kontrola vám napríklad umožňuje zachytiť zablokovanie, keď sa aplikácia zasekne na jednom mieste. Reštartovanie kontajnera v tomto stave pomáha spustiť aplikáciu napriek chybám, ale môže tiež viesť ku kaskádovým zlyhaniam (pozri nižšie).

Ak sa pokúsite nasadiť aktualizáciu aplikácie, ktorá neprejde kontrolami životnosti/pripravenosti, jej zavádzanie sa zastaví, pretože Kubernetes čaká na stav Ready zo všetkých strúčikov.

Príklad

Tu je príklad sondy pripravenosti, ktorá kontroluje cestu /health cez HTTP s predvolenými nastaveniami (interval: 10 sekúnd, timeout: 1 sekunda, prah úspešnosti: 1, prah zlyhania: 3):

# часть общего описания deployment'а/стека
podTemplate:
  spec:
    containers:
    - name: my-container
      # ...
      readinessProbe:
        httpGet:
          path: /health
          port: 8080

Odporúčanie

  1. Pre mikroslužby s koncovým bodom HTTP (REST atď.) vždy definujte sondu pripravenosti, ktorý skontroluje, či je aplikácia (pod) pripravená prijímať premávku.
  2. Uistite sa, že sonda pripravenosti pokrýva dostupnosť skutočného portu webového servera:
    • používanie portov na administratívne účely, nazývané „admin“ alebo „management“ (napríklad 9090), napr. readinessProbe, uistite sa, že koncový bod vráti OK iba vtedy, ak je primárny port HTTP (napríklad 8080) pripravený prijímať prenos*;

      *Poznám minimálne jeden prípad na Zalande, kde sa tak nestalo, t.j. readinessProbe Skontroloval som port „správa“, ale samotný server nezačal fungovať kvôli problémom s načítaním vyrovnávacej pamäte.

    • pripojenie sondy pripravenosti k samostatnému portu môže viesť k tomu, že preťaženie na hlavnom porte sa neprejaví v kontrole stavu (to znamená, že fond vlákien na serveri je plný, ale kontrola stavu stále ukazuje, že je všetko v poriadku ).
  3. Uistite sa, že sonda pripravenosti umožňuje inicializáciu/migráciu databázy;
    • Najjednoduchší spôsob, ako to dosiahnuť, je kontaktovať server HTTP až po dokončení inicializácie (napríklad migrácia databázy z Flyway a tak ďalej.); to znamená, že namiesto zmeny stavu kontroly stavu jednoducho nespúšťajte webový server, kým sa nedokončí migrácia databázy*.

      * Môžete tiež spustiť migráciu databázy z init kontajnerov mimo pod. Stále som fanúšikom samostatných aplikácií, teda takých, v ktorých aplikačný kontajner vie bez vonkajšej koordinácie uviesť databázu do požadovaného stavu.

  4. použitie httpGet na kontroly pripravenosti prostredníctvom typických koncových bodov kontroly stavu (napr. /health).
  5. Pochopte predvolené parametre kontroly (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • predvolené možnosti znamenajú, že modul sa stane nie je pripravený po asi 30 sekundách (3 neúspešné kontroly zdravého rozumu).
  6. Ak to technologický zásobník (napr. Java/Spring) umožňuje, použite samostatný port na „správu“ alebo „správu“, aby ste oddelili správu zdravia a metrík od bežnej prevádzky:
    • ale nezabudni na bod 2.
  7. Ak je to potrebné, sondu pripravenosti možno použiť na zahriatie/načítanie vyrovnávacej pamäte a vrátenie stavového kódu 503, kým sa kontajner nezahreje:
    • Tiež vám odporúčam, aby ste si prečítali nový šek startupProbe, objavil sa vo verzii 1.16 (písali sme o tom v ruštine tu - približne. preklad.).

Upozornenie

  1. Nespoliehajte sa na externé závislosti (ako sú dátové sklady) pri spustení testov pripravenosti/životnosti – môže to viesť ku kaskádovým zlyhaniam:
    • Ako príklad si vezmime stavovú službu REST s 10 modulmi v závislosti od jednej databázy Postgres: keď kontrola závisí od fungujúceho pripojenia k DB, všetkých 10 modulov môže zlyhať, ak dôjde k oneskoreniu na strane siete/DB – zvyčajne to všetko končí horšie, ako by mohlo;
    • Upozorňujeme, že Spring Data štandardne kontroluje pripojenie k databáze*;

      * Toto je predvolené správanie Spring Data Redis (aspoň to bolo naposledy, čo som to skontroloval), čo viedlo ku „katastrofickému“ zlyhaniu: keď bol Redis na krátky čas nedostupný, všetky moduly „zlyhali“.

    • „externé“ v tomto zmysle môže znamenať aj iné moduly tej istej aplikácie, to znamená, že v ideálnom prípade by kontrola nemala závisieť od stavu iných modulov toho istého klastra, aby sa predišlo kaskádovým zlyhaniam:
      • výsledky sa môžu líšiť pre aplikácie s distribuovaným stavom (napríklad ukladanie do pamäte cache v moduloch).
  2. Nepoužívajte sondu živosti pre struky (výnimkou sú prípady, keď sú skutočne potrebné a vy ste si plne vedomí špecifík a dôsledkov ich použitia):
    • Sonda životnosti môže pomôcť obnoviť zavesené kontajnery, ale keďže máte plnú kontrolu nad vašou aplikáciou, veci ako pozastavené procesy a uviaznutia by v ideálnom prípade nemali nastať: najlepšou alternatívou je zámerne zrútiť aplikáciu a vrátiť ju späť do predchádzajúceho ustáleného stavu;
    • zlyhaná sonda životnosti spôsobí reštart kontajnera, čím sa potenciálne zhoršia následky chýb súvisiacich s načítaním: reštartovanie kontajnera bude mať za následok prestoje (aspoň počas trvania spustenia aplikácie, povedzme 30 nepárnych sekúnd), čo spôsobí nové chyby , zvýšenie zaťaženia iných kontajnerov a zvýšenie pravdepodobnosti ich zlyhania atď.;
    • kontroly životnosti v kombinácii s externou závislosťou sú najhoršou možnou kombináciou, ktorá ohrozuje kaskádové zlyhania: malé oneskorenie na strane databázy povedie k reštartu všetkých vašich kontajnerov!
  3. Parametre kontroly živosti a pripravenosti musí byť iný:
    • môžete použiť sondu živosti s rovnakou kontrolou stavu, ale s vyšším prahom odozvy (failureThreshold), napríklad priradiť stav nie je pripravený po 3 pokusoch a uvážiť, že sonda živosti zlyhala po 10 pokusoch;
  4. Nepoužívajte kontroly exec, pretože sú spojené so známymi problémami, ktoré vedú k objaveniu sa zombie procesov:

Zhrnutie

  • Použite sondy pripravenosti na určenie, kedy je modul pripravený na príjem prevádzky.
  • Sondy živosti používajte len vtedy, keď sú skutočne potrebné.
  • Nesprávne používanie sond pripravenosti/životnosti môže viesť k zníženej dostupnosti a kaskádovým zlyhaniam.

Sondy živosti v Kubernetes môžu byť nebezpečné

Ďalšie materiály k téme

Aktualizácia č.1 z 2019

O init kontajneroch pre migráciu databázy: Pridaná poznámka pod čiarou.

EJ mi pripomenul o PNR: jedným z problémov pri kontrolách životnosti je nedostatočná koordinácia medzi modulmi. Kubernetes má Rozpočty na prerušenie skupiny (PNR) obmedziť počet súbežných zlyhaní aplikácie, kontroly však nezohľadňujú PNR. V ideálnom prípade by sme mohli K8 povedať: „Reštartujte jeden modul, ak jeho test zlyhá, ale nereštartujte ich všetky, aby ste predišli zhoršeniu situácie.“

Bryan to vystihol dokonale: „Používajte sondovanie živosti, keď presne viete, čo najlepšie je zabiť aplikáciu“ (opäť sa nenechajte uniesť).

Sondy živosti v Kubernetes môžu byť nebezpečné

Aktualizácia č.2 z 2019

Pokiaľ ide o prečítanie dokumentácie pred použitím: Vytvoril som zodpovedajúcu požiadavku (požiadavka funkcie) pridať dokumentáciu o sondách živosti.

PS od prekladateľa

Prečítajte si aj na našom blogu:

Zdroj: hab.com

Pridať komentár