کاوشگرهای زنده در Kubernetes می توانند خطرناک باشند

توجه داشته باشید. ترجمه: مهندس ارشد از Zalando، Henning Jacobs، بارها متوجه مشکلاتی در بین کاربران Kubernetes در درک هدف کاوشگرهای زنده (و آمادگی) و استفاده صحیح از آنها شده است. بنابراین، او افکار خود را در این یادداشت بزرگ جمع آوری کرد که در نهایت بخشی از مستندات K8s خواهد شد.

کاوشگرهای زنده در Kubernetes می توانند خطرناک باشند

چک های سلامت، که در Kubernetes به عنوان شناخته شده است کاوشگرهای زنده بودن (یعنی به معنای واقعی کلمه، "تست های زنده ماندن" - تقریباً ترجمه.)، می تواند بسیار خطرناک باشد. من توصیه می کنم در صورت امکان از آنها اجتناب کنید: تنها استثناها زمانی هستند که واقعاً ضروری هستند و شما کاملاً از ویژگی ها و عواقب استفاده از آنها آگاه هستید. این نشریه در مورد بررسی های زنده بودن و آمادگی صحبت می کند و همچنین به شما می گوید در چه مواردی هزینه و شما نباید از آنها استفاده کنید.

همکار من سندور اخیراً رایج ترین خطاهایی را که با آن مواجه می شود، از جمله موارد مربوط به استفاده از کاوشگرهای آمادگی/سرزندگی در توییتر به اشتراک گذاشته است:

کاوشگرهای زنده در Kubernetes می توانند خطرناک باشند

به اشتباه پیکربندی شده است livenessProbe می تواند موقعیت های پر بار را تشدید کند (خاموش شدن گلوله برفی + زمان راه اندازی طولانی مدت کانتینر/برنامه) و منجر به پیامدهای منفی دیگری مانند کاهش وابستگی شود. (همچنین ببینید مقاله اخیر من درباره محدود کردن تعداد درخواست‌ها در ترکیب K3s+ACME). وقتی کاوشگر زنده با یک بررسی سلامت که یک پایگاه داده خارجی است، ترکیب شود، بدتر است: یک خرابی واحد DB همه کانتینرهای شما را مجددا راه اندازی می کند!

پیام عمومی "از کاوشگرهای زنده گیری استفاده نکنید" در این مورد کمک زیادی نمی کند، بنابراین بیایید ببینیم که بررسی های آمادگی و سرزندگی برای چیست.

توجه: بیشتر تست زیر در ابتدا در اسناد توسعه دهنده داخلی Zalando گنجانده شده است.

بررسی آمادگی و سرزندگی

Kubernetes دو مکانیسم مهم به نام ارائه می دهد کاوشگرهای زنده و کاوشگر آمادگی. آنها به طور دوره ای برخی از اقدامات را انجام می دهند - مانند ارسال یک درخواست HTTP، باز کردن یک اتصال TCP یا اجرای یک فرمان در ظرف - تا تأیید کنند که برنامه مطابق انتظار کار می کند.

Kubernetes استفاده می کند کاوشگرهای آمادگیبرای درک اینکه ظرف چه زمانی برای پذیرش ترافیک آماده است. یک غلاف در صورتی آماده برای استفاده در نظر گرفته می شود که تمام ظروف آن آماده باشد. یکی از کاربردهای این مکانیسم کنترل این است که کدام پادها به عنوان پشتیبان برای سرویس های Kubernetes (و به ویژه Ingress) استفاده می شوند.

کاوشگرهای زنده بودن به Kubernetes کمک کنید تا بفهمند چه زمانی زمان راه اندازی مجدد ظرف است. به عنوان مثال، چنین بررسی به شما اجازه می دهد تا زمانی که یک برنامه در یک مکان گیر می کند، یک بن بست را متوقف کنید. راه اندازی مجدد کانتینر در این حالت به حذف برنامه علیرغم وجود خطاها کمک می کند، اما همچنین می تواند منجر به خرابی های آبشاری شود (به زیر مراجعه کنید).

اگر سعی کنید به‌روزرسانی برنامه‌ای را اجرا کنید که در بررسی‌های زنده بودن/آمادگی ناموفق باشد، عرضه آن متوقف خواهد شد زیرا Kubernetes منتظر وضعیت است. Ready از همه غلاف ها

مثال

در اینجا نمونه ای از یک کاوشگر آمادگی است که یک مسیر را بررسی می کند /health از طریق HTTP با تنظیمات پیش فرض (فاصله: 10 ثانیه، فاصله: 1 ثانیه، آستانه موفقیت: 1، آستانه شکست: 3):

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

توصیه

  1. برای میکروسرویس‌های دارای نقطه پایانی HTTP (REST و غیره) همیشه یک کاوشگر آمادگی تعریف کنید، که بررسی می کند که آیا برنامه (pod) برای پذیرش ترافیک آماده است یا خیر.
  2. از کاوشگر آمادگی مطمئن شوید در دسترس بودن پورت وب سرور واقعی را پوشش می دهد:
    • استفاده از پورت ها برای اهداف اداری، به نام "admin" یا "management" (به عنوان مثال، 9090)، برای readinessProbe، مطمئن شوید که نقطه پایانی فقط در صورتی خوب است که پورت HTTP اولیه (مانند 8080) آماده پذیرش ترافیک باشد*.

      *من حداقل از یک مورد در Zalando مطلع هستم که این اتفاق نیفتاده است، یعنی. readinessProbe من پورت "مدیریت" را بررسی کردم، اما خود سرور به دلیل مشکلات بارگیری کش شروع به کار نکرد.

    • اتصال یک کاوشگر آمادگی به یک پورت جداگانه می تواند منجر به این واقعیت شود که اضافه بار در پورت اصلی در بررسی سلامت منعکس نمی شود (یعنی مخزن نخ روی سرور پر است، اما بررسی سلامت هنوز نشان می دهد که همه چیز درست است. ).
  3. مطمئن شوید که کاوشگر آمادگی، مقدار دهی اولیه/مهاجرت پایگاه داده را فعال می کند;
    • ساده ترین راه برای رسیدن به این هدف تماس با سرور HTTP تنها پس از تکمیل اولیه سازی است (به عنوان مثال، انتقال پایگاه داده از مسیر پرواز و غیره.) یعنی به جای تغییر وضعیت بررسی سلامت، سرور وب را تا زمانی که انتقال پایگاه داده کامل نشده است راه اندازی نکنید*.

      * همچنین می توانید مهاجرت های پایگاه داده را از کانتینرهای init خارج از پاد اجرا کنید. من هنوز هم از طرفداران برنامه های کاربردی خودمختار هستم، یعنی برنامه هایی که در آنها کانتینر برنامه می داند چگونه پایگاه داده را بدون هماهنگی خارجی به حالت مطلوب برساند.

  4. استفاده کنید httpGet برای بررسی آمادگی از طریق نقاط پایانی معمولی بررسی سلامت (به عنوان مثال، /health).
  5. پارامترهای چک پیش فرض را درک کنید (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • گزینه های پیش فرض به این معنی است که غلاف تبدیل خواهد شد آماده نیست پس از حدود 30 ثانیه (3 بررسی سلامت عقل ناموفق).
  6. اگر پشته فناوری (مانند جاوا/بهار) اجازه دهد، از یک پورت جداگانه برای «مدیریت» یا «مدیریت» استفاده کنید تا مدیریت سلامت و معیارها را از ترافیک معمولی جدا کنید:
    • اما نکته 2 را فراموش نکنید.
  7. در صورت لزوم، می‌توان از کاوشگر آماده‌سازی برای گرم کردن/بارگیری حافظه پنهان و بازگرداندن کد وضعیت 503 استفاده کرد تا زمانی که ظرف گرم شود:
    • همچنین توصیه می کنم چک جدید را مطالعه کنید startupProbe, در نسخه 1.16 ظاهر شد (ما در مورد آن به روسی نوشتیم اینجا - تقریبا ترجمه.).

هشدارها

  1. به وابستگی های خارجی تکیه نکنید (مانند انبارهای داده) هنگام اجرای تست های آمادگی/زندگی - این می تواند منجر به خرابی های آبشاری شود:
    • به عنوان مثال، بیایید یک سرویس REST حالت دار با 10 پاد بسته به یک پایگاه داده Postgres را در نظر بگیریم: وقتی بررسی به یک اتصال فعال به DB بستگی دارد، اگر تاخیری در سمت شبکه/DB وجود داشته باشد، ممکن است هر 10 پاد از کار بیفتد - معمولاً همه چیز بدتر از آنچه می تواند به پایان می رسد.
    • لطفاً توجه داشته باشید که Spring Data اتصال پایگاه داده را به طور پیش فرض بررسی می کند*.

      * این رفتار پیش‌فرض Spring Data Redis است (حداقل آخرین باری بود که بررسی کردم)، که منجر به یک شکست «فاجعه‌آمیز» شد: زمانی که Redis برای مدت کوتاهی در دسترس نبود، همه غلاف‌ها از کار افتادند.

    • «خارجی» در این معنا می‌تواند به معنای سایر غلاف‌های همکار باشد، یعنی در حالت ایده‌آل، بررسی نباید به وضعیت سایر غلاف‌های همان خوشه برای جلوگیری از خرابی‌های آبشاری بستگی داشته باشد:
      • نتایج ممکن است برای برنامه های کاربردی با وضعیت توزیع متفاوت باشد (به عنوان مثال، حافظه پنهان در حافظه).
  2. از کاوشگر زنده استفاده نکنید برای غلاف (استثناء مواردی هستند که واقعاً ضروری هستند و شما کاملاً از ویژگی ها و عواقب استفاده از آنها آگاه هستید):
    • کاوشگر زنده می‌تواند به بازیابی کانتینرهای آویزان کمک کند، اما از آنجایی که شما کنترل کاملی بر برنامه خود دارید، مواردی مانند فرآیندهای آویزان و بن‌بست‌ها در حالت ایده‌آل نباید اتفاق بیفتند: بهترین جایگزین این است که برنامه را عمداً خراب کنید و آن را به حالت ثابت قبلی بازگردانید.
    • یک کاوشگر زنده ناموفق باعث راه اندازی مجدد کانتینر می شود و در نتیجه به طور بالقوه عواقب خطاهای مربوط به بارگیری را تشدید می کند: راه اندازی مجدد کانتینر منجر به خرابی (حداقل برای مدت زمان راه اندازی برنامه، مثلاً 30 ثانیه فرد) می شود و باعث خطاهای جدید می شود. افزایش بار روی ظروف دیگر و افزایش احتمال خرابی آنها و غیره.
    • بررسی‌های زنده‌گی همراه با وابستگی خارجی بدترین ترکیب ممکن است، که شکست‌های آبشاری را تهدید می‌کند: یک تاخیر جزئی در سمت پایگاه داده منجر به راه‌اندازی مجدد همه کانتینرهای شما می‌شود!
  3. پارامترهای بررسی زنده بودن و آمادگی باید متفاوت باشد:
    • شما می توانید از یک کاوشگر زنده با همان بررسی سلامت استفاده کنید، اما آستانه پاسخ بالاتر (failureThresholdبه عنوان مثال، وضعیت را تعیین کنید آماده نیست پس از 3 تلاش و در نظر بگیرید که کاوشگر زنده پس از 10 تلاش شکست خورده است.
  4. از چک های exec استفاده نکنید، زیرا آنها با مشکلات شناخته شده ای مرتبط هستند که منجر به ظهور فرآیندهای زامبی می شود:

خلاصه

  • از کاوشگرهای آمادگی برای تعیین اینکه چه زمانی یک غلاف برای دریافت ترافیک آماده است استفاده کنید.
  • از کاوشگرهای زنده فقط زمانی استفاده کنید که واقعاً مورد نیاز هستند.
  • استفاده نادرست از کاوشگرهای آمادگی/زندگی می تواند منجر به کاهش در دسترس بودن و خرابی های آبشاری شود.

کاوشگرهای زنده در Kubernetes می توانند خطرناک باشند

مطالب اضافی در مورد موضوع

به روز رسانی شماره 1 از 2019-09-29

درباره کانتینرهای init برای انتقال پایگاه داده: پاورقی اضافه شد.

ای جی به من یادآوری کرد درباره PDB: یکی از مشکلات بررسی زنده بودن، عدم هماهنگی بین غلاف ها است. Kubernetes دارد بودجه های اختلال پاد (PDB) برای محدود کردن تعداد خرابی های همزمان که یک برنامه می تواند تجربه کند، اما بررسی ها PDB را در نظر نمی گیرند. در حالت ایده‌آل، می‌توانیم به K8s بگوییم: «اگر یک پاد شکست خورد، آن را دوباره راه‌اندازی کنید، اما همه آن‌ها را مجددا راه‌اندازی نکنید تا اوضاع بدتر نشود».

برایان آن را کاملاً بیان کرد: «زمانی که دقیقاً می دانید از کاوشگر زنده استفاده کنید بهترین کار این است که برنامه را از بین ببرید"(باز هم گمراه نشوید).

کاوشگرهای زنده در Kubernetes می توانند خطرناک باشند

به روز رسانی شماره 2 از 2019-09-29

با توجه به مطالعه مستندات قبل از استفاده: من درخواست مربوطه را ایجاد کردم (درخواست ویژگی) برای افزودن مستندات در مورد کاوشگرهای زنده.

PS از مترجم

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

اضافه کردن نظر