المستوى المطلوب: متوسط — مناسب لمن يشتغل على Kubernetes في الإنتاج وعنده فهم أساسي للـ Pods و Services و Deployments.
لو الـ pod بتاعك في Kubernetes بيتعمله restart كل دقيقتين، وفي الـ logs بتلاقي Liveness probe failed: HTTP probe failed with statuscode: 503، المشكلة غالبًا مش إن التطبيق بيقع. المشكلة إنك خلطت بين Liveness و Readiness، والـ kubelet بيقتل container شغّال كل ما الـ DB تتأخر ثانية. الفرق بين الاتنين سطرين YAML، وبيوفروا 90% من حوادث الـ restart غير المبررة.
Liveness vs Readiness Probes في Kubernetes
المشكلة باختصار
Kubernetes محتاج يعرف حاجتين عن كل container:
- هل لسه شغّال ولا اتعلّق وعايز restart؟ (Liveness)
- هل جاهز يستقبل traffic دلوقتي ولا لسه بيـ warm up؟ (Readiness)
المطورين بيستخدموا نفس الـ endpoint للـ probes الاتنين، أو بيخلطوا قواعدهم. النتيجة: pods بتتقتل وهي شغّالة، أو traffic بيوصل لـ pod مش جاهز فبترد 502.
المفهوم بمثال بسيط — البواب والمطعم
تخيّل مطعم فيه بواب على الباب وشيف في المطبخ:
- البواب بيشيك إن الشيف لسه عايش وبيتنفّس — ده الـ Liveness. لو الشيف وقع، البواب يستدعي شيف بديل.
- الجرسون بيشيك إن الشيف فاضي ومستعد ياخد أوردر دلوقتي — ده الـ Readiness. لو الشيف بيقطّع بصل، الجرسون يحوّل الزبون لطاولة تانية.
لو خلطت الاتنين، البواب هيرمي الشيف بره كل ما يكون بيقطّع بصل. ده بالظبط اللي بيحصل في Kubernetes لما الـ Liveness بيشيك على نفس endpoint اللي بيتأخر وقت ضغط الـ DB.
التعريف العلمي الدقيق
بعد المثال، التعريف الرسمي من توثيق Kubernetes:
- Liveness Probe: لو فشلت
failureThresholdمرة متتالية، الـ kubelet بيعمل restart للـ container. الهدف: اكتشاف الـ deadlock داخل process شغّال ظاهريًا. - Readiness Probe: لو فشلت، الـ pod بيتشال من الـ Service endpoints — بس مش بيتعمله restart. الهدف: حماية الترافيك من الوصول لـ instance غير جاهز.
- Startup Probe: بيتنفّذ مرة واحدة عند البدء، وبيوقف الـ Liveness و Readiness لحد ما ينجح. الهدف: إعطاء وقت للتطبيقات بطيئة الإقلاع (Java/Spring/Rails) من غير ما الـ Liveness يقتلها قبل ما تخلّص boot.
الإعداد الصح — YAML قابل للنسخ
ده Deployment أساسي على تطبيق Node.js بيتصل بـ PostgreSQL و Redis. بنفصل الـ probes الثلاثة بـ endpoints مختلفة:
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders-api
spec:
replicas: 3
selector:
matchLabels: { app: orders-api }
template:
metadata:
labels: { app: orders-api }
spec:
containers:
- name: api
image: registry.local/orders-api:1.8.2
ports:
- containerPort: 3000
startupProbe:
httpGet: { path: /health/startup, port: 3000 }
failureThreshold: 30
periodSeconds: 2
livenessProbe:
httpGet: { path: /health/live, port: 3000 }
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
httpGet: { path: /health/ready, port: 3000 }
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2