الفحوصات: الحيوية والجاهزية والبدء
الفحوصات: الحيوية والجاهزية والبدء
لا تستطيع Kubernetes قراءة أفكار تطبيقك. تعرف أن الحاوية "تعمل" فور بدء العملية — لكن "تعمل" و"بصحة جيدة" أمران مختلفان تمامًا. قد تحتاج خدمة Java إلى 45 ثانية لتهيئة ذاكرتها المؤقتة. وقد يُصاب برنامج Go بحالة إغلاق تام دون أن يتعطل. وقد يبدأ خادم ويب باستقبال حركة المرور قبل أن يكون مجمّع اتصالات قاعدة البيانات جاهزًا. الفحوصات (Probes) هي الآلية التي تستخدمها Kubernetes للتمييز بين Pod سليم وجاهز، وآخر معطل أو في طور التهيئة أو مثقّل مؤقتًا.
الإعداد الخاطئ للفحوصات هو أحد أكثر أسباب حوادث الإنتاج شيوعًا في Kubernetes. إما أن تكون عدوانية للغاية فتتسبب في قتل Pods سليمة خلال ذروة حركة المرور، أو متساهلة للغاية فتوجّه الحركة إلى Pod غير قادر على خدمة الطلبات. تغطي هذه الدرس الأنواع الثلاثة للفحوصات وأوضاع فشلها وما تُعدّه فرق SRE في كبرى شركات التقنية فعليًا.
الأنواع الثلاثة للفحوصات
- فحص الحيوية (Liveness) — يجيب عن السؤال: "هل هذه الحاوية لا تزال حية؟" إذا فشل، تقوم kubelet بإنهاء الحاوية وإعادة تشغيلها وفقًا لـ
restartPolicyالخاص بالـ Pod. - فحص الجاهزية (Readiness) — يجيب عن السؤال: "هل هذه الحاوية جاهزة لاستقبال حركة المرور؟" إذا فشل، تُحذف الـ Pod من نقاط النهاية (Endpoints) الخاصة بكل Service مطابقة (توقف الحركة عنها) لكنها لا تُعاد تشغيلها.
- فحص البدء (Startup) — يجيب عن السؤال: "هل انتهت هذه الحاوية من عملية الإقلاع البطيئة؟" طوال فترة انتظاره، يُعلَّق فحصا الحيوية والجاهزية. يعمل مرة واحدة عند الإطلاق، وبمجرد نجاحه لا يعمل مجددًا.
آليات الفحص
تدعم الأنواع الثلاثة من الفحوصات ثلاث آليات للتحقق:
httpGet— ترسل kubelet طلب HTTP GET. أي استجابة 2xx أو 3xx تعني النجاح. استخدمها لخدمات HTTP لأنها تختبر الطبقة الكاملة أيضًا.tcpSocket— تفتح kubelet اتصال TCP. النجاح = المنفذ مفتوح. استخدمها للبروتوكولات غير HTTP مثل gRPC وRedis وPostgres.exec— تنفّذ kubelet أمرًا داخل الحاوية. كود الخروج 0 = نجاح. استخدمها عند الحاجة لفحوصات على مستوى التطبيق. تجنّبها للفحوصات عالية التكرار: تنشئexecعملية جديدة في كل مرة.grpc(k8s نسخة 1.24+) — تستدعي kubelet بروتوكول gRPC لفحص الصحة. مثالية للخدمات الأصيلة للـ gRPC.
معاملات الضبط المهمة
initialDelaySeconds— المدة التي تنتظرها بعد بدء الحاوية قبل أول فحص. مطلوبة إذا لم يكن لديك فحص بدء.periodSeconds— مدة الانتظار بين كل فحص وآخر. الافتراضي 10 ثوانٍ.timeoutSeconds— المدة التي تنتظر فيها kubelet الاستجابة. الافتراضي ثانية واحدة — خطير للغاية لأي شيء يصل إلى قاعدة بيانات.failureThreshold— عدد الفشل المتتالي قبل اعتبار الفحص فاشلًا. الافتراضي 3.successThreshold— عدد النجاح المتتالي للانتقال من فاشل إلى ناجح. يجب أن يكون 1 لفحصي الحيوية والبدء.
مانيفست جاهز للإنتاج
فيما يلي مانيفست Deployment واقعي لخدمة Spring Boot ذات إحماء مدته 40 ثانية. يستخدم الأنواع الثلاثة من الفحوصات بشكل صحيح:
فحص البدء: لماذا وُجد؟
قبل ظهور فحوصات البدء (k8s < 1.16)، كانت الفرق تستخدم initialDelaySeconds كبيرًا على فحص الحيوية لتغطية الإقلاع البطيء. المشكلة: إذا تجمّد Pod أثناء الإقلاع، لن تكتشف kubelet ذلك حتى تنتهي مدة التأخير. تحل فحوصات البدء هذه المشكلة بأناقة — تمنح نافذة إقلاع سخية مع الكشف السريع عن التجمّد بعد الإقلاع.
الصيغة هي: أقصى وقت إقلاع = failureThreshold × periodSeconds. اضبطها على 150-200% من وقت الإقلاع البارد المقاس عند النسبة المئوية 99. للمانيفست أعلاه: 6 × 10s = 60 ثانية.
أنماط الفشل الشائعة في الإنتاج
- فحص الحيوية يصل إلى قاعدة البيانات — إذا كانت قاعدة البيانات بطيئة، يتجاوز الفحص المهلة الزمنية، تقتل kubelet Pods سليمة، وتدخل في حلقة تعطل تزيد الحمل على قاعدة البيانات. يجب أن يتحقق فحص الحيوية من العملية ذاتها فقط.
- timeoutSeconds: 1 (الافتراضي) على فحص الجاهزية — يمكن لنقطة نهاية بمدة استجابة 200ms عند P99 أن تأخذ أحيانًا 2 ثانية تحت ضغط جمع البيانات غير المستخدمة. مهلة واحدة تُعدّ فشلًا. مع
failureThreshold: 3هذا 3 ثوانٍ فقط من التأخير قبل البدء بتصريف الـ Pod. اضبطtimeoutSecondsعلى الأقل عند P99 × 3. - لا فحص بدء مع initialDelaySeconds صغير على JVM بطيء — تُطلق kubelet فحص الحيوية قبل انتهاء JVM من التحميل، ترى فشلًا، وتقتل الحاوية. تدخل الـ Pod في حلقة تعطل ولا تبدأ أبدًا. إضافة فحص بدء مع
failureThresholdمناسب هو الحل. - نقطة نهاية جاهزية لا تفشل أبدًا — فحص جاهزية يُعيد 200 دائمًا حتى تحت الحمل الزائد لا يوفر أي حماية؛ تستمر حركة المرور في التوجه نحو Pod مشبعة. نفّذ منطق ضغط عكسي (مثلًا: أعد 503 عندما يتجاوز عمق طابور الطلبات حدًا معينًا).
failureThreshold من الفشل يقتل Pod سليمة تنتظر تبعية خارجية. وهكذا يتسبب انقطاع قاعدة البيانات في عاصفة إعادة تشغيل للـ Pods.
فحص حالة الفحوصات
استخدم kubectl describe pod <name> وانظر إلى قسم Events وكتلة Containers. تظهر أعطال الفحوصات كأحداث تحذيرية بسبب Unhealthy. يعكس العمود READY في kubectl get pod (مثل 0/1) حالة فحص الجاهزية.
فحص Exec للخدمات غير HTTP
بالنسبة لـ Redis sidecar أو Pod قاعدة بيانات، يُعدّ فحص exec الأسلوب الأمثل:
timeoutSeconds < 2، أو فحوصات حيوية تستعلم تبعيات خارجية. تُعامَل الفحوصات كعقد موثوقية، وليست لمسة نهائية.