Liveness probes у Kubernetes могуць быць небяспечныя

Заўв. перав.: Вядучы інжынер з кампаніі Zalando - Henning Jacobs - не раз заўважаў у карыстальнікаў Kubernetes праблемы ў разуменні прызначэння liveness (і readiness) probes і іх карэктнага прымянення. Таму ён сабраў свае думкі ў гэтую ёмістую нататку, якая з часам стане часткай дакументацыі K8s.

Liveness probes у Kubernetes могуць быць небяспечныя

Праверкі стану, вядомыя ў Kubernetes як liveness probes (г.зн., даслоўна, «тэсты на жыццяздольнасць» - заўв. перакл.), могуць быць вельмі небяспечнымі. Рэкамендую па магчымасці пазбягаць іх: выключэннямі з'яўляюцца толькі выпадкі, калі яны сапраўды неабходны і вы цалкам усведамляеце спецыфіку і наступствы іх выкарыстання. У гэтай публікацыі гаворка пойдзе пра liveness- і readiness-праверкі, а таксама будзе расказана, у якіх выпадках варта і не варта іх ужываць.

Мой калега Sandor нядаўна падзяліўся ў Twitter'е самымі частымі памылкамі, якія яму сустракаюцца, у тым ліку злучанымі з выкарыстаннем readiness/liveness probes:

Liveness probes у Kubernetes могуць быць небяспечныя

Няправільна настроеная livenessProbe можа пагоршыць сітуацыі з высокай нагрузкай (лавінападобнае адключэнне + патэнцыйна доўгі запуск кантэйнера/прыкладанні) і прывесці да іншых негатыўных наступстваў накшталт падзення залежнасцяў (гл. таксама мой нядаўні артыкул аб абмежаванні колькасці запытаў у звязку K3s+ACME). Яшчэ горш, калі liveness probe спалучаецца з праверкай здароўя залежнасці (health check'ом), у ролі якой выступае знешняя база дадзеных: адзіны збой БД перазапусціць усе вашыя кантэйнеры!

Агульны пасыл "Не выкарыстоўвайце liveness probes" у дадзеным выпадку дапамагае мала, таму разгледзім, для чаго прызначаны readiness- і liveness-праверкі.

Заўвага: большая частка прыведзенага ніжэй тэста першапачаткова была ўключана ва ўнутраную дакументацыю для распрацоўшчыкаў Zalando.

Праверкі Readiness і Liveness

Kubernetes дае два важных механізму, званых liveness probes і readiness probes. Яны перыядычна выконваюць некаторае дзеянне - напрыклад, пасылаюць HTTP-запыт, адчыняюць TCP-злучэнне або выконваюць каманду ў кантэйнеры, - каб пацвердзіць, што прыкладанне працуе належным чынам.

Kubernetes выкарыстоўвае readiness probes, Каб зразумець, калі кантэйнер гатовы прымаць трафік. Pod лічыцца гатовым да працы, калі ўсе яго кантэйнеры гатовы. Адно з ужыванняў гэтага механізму складаецца ў тым, каб кантраляваць, якія pod'ы выкарыстоўваюцца ў якасці бэкэндаў для сэрвісаў Kubernetes (і асабліва Ingress'а).

Liveness probes дапамагаюць Kubernetes зразумець, калі прыйшоў час перазапусціць кантэйнер. Напрыклад, падобная праверка дазваляе перахапіць deadlock, калі дадатак «захрасае» на адным месцы. Перазапуск кантэйнера ў такім стане дапамагае ссунуць дадатак з мёртвай кропкі, нягледзячы на ​​памылкі, пры гэтым ён жа можа прывесці да каскадных збояў (гл. ніжэй).

Калі вы паспрабуеце разгарнуць абнаўленне прыкладання, якое правальвае праверкі liveness/readiness, яго выкочванне спыніцца, паколькі Kubernetes будзе чакаць статуту Ready ад усіх pod'аў.

Прыклад

Вось прыклад readiness probe, якая правярае шлях /health праз HTTP з наладамі па змаўчанні (інтэрвал: 10 секунд, Тайм-аўт: 1 секунда, success threshold: 1, failure threshold: 3):

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

Рэкамендацыі

  1. Для мікрасэрвісаў з HTTP endpoint'ам (REST і да т.п.) заўсёды вызначайце readiness probe, якая правярае, ці гатова дадатак (pod) прымаць трафік.
  2. Упэўніцеся, што readiness probe пакрывае гатоўнасць фактычнага порта вэб-сервера:
    • выкарыстоўваючы парты для адміністрацыйных патрэб, званых «admin» ці «management» (напрыклад, 9090), для readinessProbe, пераканайцеся, што endpoint вяртае ОК толькі ў тым выпадку, калі асноўны HTTP-порт (накшталт 8080) готаў прымаць трафік*;

      * Мне вядома па меншай меры аб адным выпадку ў Zalando, калі гэтага не адбылося, гэта значыць readinessProbe праверыла порт "management", але сам сервер так і не пачаў працаваць з-за праблем з загрузкай кэша.

    • навешванне readiness probe на асобны порт можа прывесці да таго, што перагрузка на асноўным порце не будзе адлюстроўвацца ў health check'е (гэта значыць пул струменяў на серверы запоўнены, аднак health check па-ранейшаму паказвае, што ўсё ОК).
  3. Пераканайцеся, што readiness probe уключае ініцыялізацыю/міграцыю базы дадзеных;
    • самы просты спосаб дамагчыся гэтага – звяртацца да HTTP-сервера толькі пасля заканчэння ініцыялізацыі (напрыклад, міграцыі БД з Пралётны шлях і да т.п.); гэта значыць замест таго, каб мяняць статус health check'а, проста не запускайце вэб-сервер да завяршэння міграцыі БД*.

      * Таксама можна запускаць міграцыі БД з init-кантэйнераў звонку pod'а. Я па-ранейшаму з'яўляюся прыхільнікам самастойных (self-contained) прыкладанняў, гэта значыць такіх, у якіх кантэйнер прыкладання без знешняй каардынацыі ведае, як прывесці БД у патрэбны стан.

  4. выкарыстоўвайце httpGet для readiness-праверак праз тыповыя endpoint'ы health check'ов (напрыклад, /health).
  5. Разбярыцеся ў параметрах праверак, зададзеных па змаўчанні (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • параметры па змаўчанні азначаюць, што pod стане not-ready прыкладна праз 30 секунд (3 няўдалых праверак працаздольнасці).
  6. Выкарыстоўвайце асобны порт для "admin" або "management", калі тэхналагічны стэк (да прыкладу, Java/Spring) дазваляе гэта, каб аддзяліць кіраванне "здароўем" і метрыкамі ад звычайнага трафіку:
    • але не забывайце аб пункце 2.
  7. Пры неабходнасці readiness probe можна выкарыстоўваць для разагравання/загрузкі кэша і вяртаць код стану 503, пакуль кантэйнер не "разагрэецца":

засцярогі

  1. Не спадзявайцеся на знешнія залежнасці (такія як сховішчы дадзеных) пры правядзенні тэстаў на readiness/liveness - гэта можа прывесці да каскадных збояў:
    • у якасці прыкладу возьмем stateful-сэрвіс REST з 10-ю pod'амі, якія залежаць ад адной базы дадзеных Postgres: калі праверка залежыць ад працавальнага падлучэння да БД, усе 10 pod'аў могуць зваліцца, калі паўстане затрымка ў сетцы/на боку БД. звычайна ўсё гэта заканчваецца горш, чым магло б;
    • звярніце ўвагу, што Spring Data па змаўчанні правярае злучэнне з БД*;

      * Такія паводзіны па змаўчанні Spring Data Redis (прынамсі, яно было такім, калі я правяраў у мінулы раз), што прывяло да «катастрафічнага» збою: калі на кароткі час Redis апынуўся недаступны, усе pod'ы «упалі».

    • "вонкавы" у дадзеным сэнсе таксама можа азначаць іншыя pod'ы таго ж прыкладанні, гэта значыць у ідэале праверка не павінна залежаць ад стану іншых pod'аў таго ж кластара для прадухілення каскадных падзенняў:
      • вынікі могуць вар'іравацца для прыкладанняў з размеркаваным станам (напрыклад, in-memory-кэшаванне ў pod'ах).
  2. Не выкарыстоўвайце liveness probe для pod'ов (выключэннямі з'яўляюцца выпадкі, калі яны сапраўды неабходны і вы цалкам усведамляеце спецыфіку і наступствы іх ужывання):
    • liveness probe можа спрыяць аднаўленню «завіслых» кантэйнераў, але, паколькі вы маеце поўны кантроль над сваім дадаткам, такіх рэчаў, як «завіслыя» працэсы і deadlock'і, у ідэале не павінна здарацца: лепшай альтэрнатывай з'яўляецца наўмыснае падзенне дадатку і яго вяртанне да папярэдняму ўстойліваму стану;
    • няўдалая liveness probe прывядзе да перазапуску кантэйнера, тым самым патэнцыйна пагаршаючы наступствы памылак, звязаных з загрузкай: перазапуск кантэйнера прывядзе да прастою (прынамсі, на час запуску прыкладання, скажам, на 30 з лішнім секунд), выклікаючы новыя памылкі, павялічваючы нагрузку на іншыя кантэйнеры і падвышаючы верагоднасць іх збою, і г.д.;
    • liveness-праверкі ў спалучэнні з знешняй залежнасцю - горшая з магчымых камбінацый, якая пагражае каскаднымі адмовамі: нязначная затрымка на баку БД прывядзе да перазапуску ўсіх вашых кантэйнераў!
  3. Параметры liveness- і readiness-праверак павінны быць рознымі:
    • можна выкарыстоўваць liveness probe з тым жа health check'ом, але больш высокім парогам спрацоўвання (failureThreshold), напрыклад, прысвойваць статус not-ready пасля 3 спроб і лічыць, што liveness probe праваліўся пасля 10 спроб;
  4. Не выкарыстоўвайце exec-праверкі, паколькі з імі звязаны вядомыя праблемы, якія прыводзяць да з'яўлення зомбі-працэсаў:

Рэзюмэ

  • Выкарыстоўвайце readiness probes, каб вызначыць, калі pod гатовы прымаць трафік.
  • Выкарыстоўвайце liveness probes толькі тады, калі яны сапраўды неабходны.
  • Няправільнае выкарыстанне readiness/liveness probes можа прывесці да зніжэння даступнасці і каскадных збояў.

Liveness probes у Kubernetes могуць быць небяспечныя

Дадатковыя матэрыялы па тэме

Абнаўленне №1 ад 2019-09-29

Аб init-кантэйнерах для міграцыі БД: дададзена зноска.

EJ нагадаў мне аб PDB: адна з бед liveness-праверак - адсутнасць каардынацыі паміж pod'амі. У Kubernetes ёсць Pod Disruption Budgets (PDB) для абмежавання колькасці паралельных збояў, якое можа адчуваць дадатак, аднак праверкі не ўлічваюць PDB. У ідэале мы можам загадаць K8s: "Перазапусці адзін pod, калі яго праверка апынецца няўдалай, але не перазапускай іх усё, каб не зрабіць яшчэ горш".

Bryan выдатна сфармуляваў: «Выкарыстоўвайце liveness-зандаванне, калі дакладна ведаеце, што лепшае, што можна зрабіць, - гэта «забіць» дадатак»(зноў жа, захапляцца не варта).

Liveness probes у Kubernetes могуць быць небяспечныя

Абнаўленне №2 ад 2019-09-29

Датычна чытання дакументацыі перад выкарыстаннем: я стварыў адпаведны запыт (запыт функцыі) на дадатак дакументацыі аб liveness probes.

PS ад перакладчыка

Чытайце таксама ў нашым блогу:

Крыніца: habr.com

Дадаць каментар