Liveness و Readiness Probes: الفرق اللي بيوقف موقعك أو ينقذه
يتطلب مستوى مبتدئ. بعد المقال ده هتعرف بالظبط إمتى Kubernetes بيقطع الترافيك عن تطبيقك، وإمتى بيعيد تشغيله، وهتبطّل تعمل الغلطة الشائعة اللي بتحوّل بطء بسيط في قاعدة البيانات لسقوط كامل للخدمة.
الحكاية كلها في سؤالين مختلفين: "هل التطبيق جاهز يستقبل طلبات دلوقتي؟" و"هل التطبيق لسه حيّ أصلاً؟". خلط السؤالين مع بعض هو السبب رقم واحد في حوادث الـ restart المتتالي.
المشكلة باختصار
لما تعمل deploy، الـ Pod بياخد وقت لحد ما التطبيق يجهز فعلاً. لو Kubernetes بعت ترافيك عليه قبل ما يجهز، المستخدم بياخد أخطاء 502/503. وعلى الناحية التانية، لو التطبيق "علّق" (deadlock) وفضل شغّال بالاسم بس مش بيرد على أي طلب، محدش هيصلّحه غير لو حد قرر يعيد تشغيله يدويًا. Kubernetes بيحل المشكلتين دول بأداتين منفصلتين، وأغلب الناس بتستخدمهم بالغلط.
مثال بسيط الأول
خُد الموقف ده: سلسلة مطاعم فتحت فروع جديدة. عند باب كل فرع فيه حارس بيبص جوه ويقرر حاجتين مختلفتين تمامًا. الأولى: هل الفرع جاهز يستقبل زباين دلوقتي؟ لو المطبخ لسه بيسخّن، الحارس بيمنع دخول الزباين مؤقتًا، لكنه مش بيقفل الفرع. الثانية: هل الموظفين جوه لسه صاحيين وبيشتغلوا، ولا الفرع اتشلّ وفضل مفتوح على الفاضي؟ لو اتشلّ، الحارس بيقفله ويفتحه من الأول.
الحارس ده بالظبط هو الـ kubelet. القرار الأول هو readinessProbe (امنع الترافيك مؤقتًا). القرار التاني هو livenessProbe (اقتل وأعد التشغيل). دلوقتي نشوف ده علميًا.
الشرح العلمي: مين بيعمل إيه
الـ kubelet هو الوكيل اللي بيدير الـ Pods على كل node، وهو اللي بيشغّل الفحوص على فترات منتظمة. كل فحص نتيجته نجاح أو فشل. الفرق الحقيقي في اللي بيحصل بعد الفشل:
- livenessProbe: لو فشل عدد مرات متتالية (failureThreshold)، الـ kubelet بيقتل الـ container ويعيد تشغيله، وعدّاد restartCount بيزيد. الهدف: إنقاذ عملية معلّقة.
- readinessProbe: لو فشل، الـ Pod بيتشال من قائمة الـ Endpoints بتاعة الـ Service، فالترافيك يبطّل يتوجّه له — من غير ما يتقتل. الهدف: امنع الترافيك طول ما التطبيق مش جاهز.
وفيه فحص تالت اسمه startupProbe، للتطبيقات اللي بتاخد وقت في الإقلاع. ده بيوقف الـ liveness من إنه يقتل التطبيق وهو لسه بيسخّن.
الغلطة اللي بتوقّع الخدمة كلها
الطريقة الشائعة الغلط: تربط livenessProbe على endpoint بيفحص قاعدة البيانات أو خدمة خارجية. تعالَ نشوف اللي بيحصل فعلاً. الافتراض إن عندك 12 Pod بيخدموا 2000 طلب/ثانية. أول ما Postgres تاخد لحظة بطء (بسبب vacuum، أو نتوة شبكة)، الـ liveness بيفشل على الـ 12 Pod في نفس اللحظة. Kubernetes بيقتلهم كلهم ويعيد تشغيلهم مع بعض، فالخدمة تقع بالكامل، والـ DB اللي كانت بتتنفس تتضرب تاني بموجة إعادة اتصال. كده حوّلت بطء 3 ثواني لسقوط دقيقة أو أكتر.
القاعدة اللي بتفرق: liveness لازم يبقى خفيف وداخلي — يرد 200 طول ما الـ process شغّال ومش معلّق، من غير ما يلمس أي اعتمادية. و هو اللي ممكن يفحص الاعتماديات. كده لو الـ DB بطّأت، الـ Pods تتشال من الترافيك مؤقتًا وترجع لوحدها من غير أي restart.