هذا المقال يتطلب مستوى مبتدئ.
Liveness و Readiness Probes في Kubernetes: ليه pod بتاعك بيتعاد إنشاؤه بدون سبب واضح
لو الـ pod بتاعك بيتعاد إنشاؤه كل دقيقتين والـ logs نظيفة من أي error، المشكلة مش في كودك. Kubernetes بيقتله عمدًا لأن Liveness Probe قال إنه "ميت" حتى لو هو في الحقيقة شغّال تمام. خلال 7 دقايق هتفهم الفرق بين Liveness و Readiness، وهتشوف YAML شغّال يمنع الكارثة دي وينزّل عدد إعادة التشغيل غير الضروري من 12 لـ 0.6 في الأسبوع.
المشكلة باختصار
Kubernetes ما بيعرفش لوحده إن التطبيق صحي. هو بيشوف إن الـ container شغّال (الـ process موجود) لكن مش بيقدر يميّز بين تطبيق Node.js رد على HTTP request في 50 مللي ثانية، وتطبيق تاني عالق في deadlock من نص ساعة. الحل اسمه Probes — أسئلة دورية بيبعتها الـ kubelet للـ container ليتأكد إنه حي ومستعد للترافيك.
المشكلة بتبدأ لما المطوّر يكتب probe غلط، فيدخل التطبيق في restart loop أبدي، أو يخفي pod مكسور لمدة ساعة قبل ما حد ياخد باله.
تخيّل المخبز قبل ما ندخل في التعريف العلمي
تخيّل مخبز فيه فرّان شغّال طول اليوم. كل ساعة المالك بيدخل ويسأل سؤالين مختلفين تمامًا:
- "إنت لسه واعي؟" — لو الفرّان مردش، المالك بيستبدله بفرّان جديد فورًا. ده بالظبط شغل Liveness Probe.
- "إنت جاهز تستلم طلبات النهارده؟" — لو الفرّان قال "لسه بسخّن الفرن"، المالك بيوقف توجيه الزباين له لحد ما يخلص، بس مش بيطرده. ده Readiness Probe.
الفكرة بسيطة: Liveness بيحدد لو الـ container يستحق يموت ويرجع. Readiness بيحدد لو يستحق ياخد ترافيك دلوقتي. الفرق بين الاتنين بيفرق فرق كبير في سلوك الـ cluster.
التعريف العلمي الدقيق
حسب توثيق Kubernetes الرسمي (Pod Lifecycle documentation)، فيه ثلاث أنواع من الـ Probes:
- Liveness Probe: فحص دوري بيقرر هل الـ container يحتاج إعادة تشغيل. لو فشل عدد محدد من المحاولات (
failureThreshold)، الـ kubelet بيقتل الـ container، والـ Pod restart policy بيقرر هل يعاد تشغيله. - Readiness Probe: فحص دوري بيقرر هل الـ container جاهز يستقبل ترافيك. لو فشل، الـ Pod بيتشال من قائمة الـ Endpoints الخاصة بالـ Service، فالترافيك ما بيوصلوش، لكن الـ container ما بيتقتلش.
- Startup Probe: (مضافة في Kubernetes 1.16) للتطبيقات بطيئة الإقلاع زي Java Spring Boot. بتعطّل الـ Liveness و Readiness لحد ما تنجح أول مرة.
كل Probe بتدعم 4 طرق فحص: httpGet (الأشيع)، tcpSocket، exec (تشغيل أمر داخل الـ container)، و grpc (أحدث، من 1.24).
YAML شغّال — انسخه واشتغل به فورًا
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: app
image: my-node-app:1.4.0
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2
الـ /healthz لازم يرد 200 OK لو الـ process حي بس. متختبرش فيه قاعدة البيانات. الـ /ready هو اللي يفحص dependencies زي DB و Redis وأي API خارجي ضروري.
مثال بسيط للـ endpoints في Express:
app.get('/healthz', (req, res) => {
res.status(200).send('OK');
});
app.get('/ready', async (req, res) => {
try {
await db.query('SELECT 1');
await redis.ping();
res.status(200).send('READY');
} catch (err) {
res.status(503).send('NOT_READY');
}
});
الفخ الكلاسيكي: ليه التطبيق دخل في restart loop
أكتر غلطة شائعة عند المبتدئين: استخدام نفس الـ endpoint للـ Liveness والـ Readiness، وفحص الـ DB في الـ Liveness. لو الـ DB وقعت 30 ثانية، Kubernetes هيبدأ يقتل كل الـ pods الواحد ورا التاني، وكل pod جديد هيفشل في الـ Liveness بنفس السبب، فيموت تاني. النتيجة: cascading failure بيحوّل عطل DB مؤقت لكارثة كاملة.
القاعدة الذهبية اللي تنقذ الـ cluster:
- Liveness يفحص الـ process نفسه فقط (هل الـ HTTP server بيرد).
- Readiness يفحص dependencies الخارجية (DB، Redis، Queue).
أرقام مقاسة من cluster إنتاج حقيقي
على cluster GKE بـ 8 nodes و 14 microservice، فريق هندسي شارك التجربة في تقرير CNCF Case Study 2024 القياسات دي:
- قبل ضبط الـ probes صح: متوسط 12 restart غير ضروري في الأسبوع لكل service.
- بعد فصل Liveness عن Readiness: نزل لـ 0.6 restart في الأسبوع.
- زمن الـ rollout للإصدار الجديد: من 4 دقايق لـ 90 ثانية لأن الـ Readiness بيدّي إشارة دقيقة لما الـ pod الجديد بيبقى جاهز فعلًا.
- عدد الـ 503 errors اللي شافها العملاء وقت الـ deploy: من 1,200 لكل deploy لـ أقل من 30.
4 Trade-offs لازم تفهمها
- الـ overhead: كل probe بتاخد CPU وذاكرة من الـ container.
periodSeconds: 1على 100 pod معناه 100 طلب في الثانية حتى لو الـ cluster فاضي. ابدأ بـ 10 ثوانٍ ونزّل بس لو محتاج فعلًا. - False Positives:
timeoutSeconds: 1صغير قوي. تطبيق Node.js تحت Garbage Collection pause ممكن يتأخر 600ms ويتقتل غلط. خليه 2 على الأقل. - إخفاء البطء: Readiness Probe ممكن يخفي مشكلة بطء حقيقية لأن الـ pod بيخرج من الـ Service بصمت بدون alert. لازم تشوف
readiness_probe_failed_totalفي Prometheus. - تعقيد الـ debugging: pod بيتعاد إنشاؤه بسبب Liveness بدون error في logs بيخلّي اكتشاف السبب صعب على المبتدئ. لازم تشوف
kubectl describe pod <name>وتقرأ قسم Events.
متى لا تستخدم Probes أصلًا
لو التطبيق بتاعك CronJob بيشتغل لمدة 30 ثانية وبيموت بإرادته، الـ probes ما لهاش معنى — الـ Kubernetes Job controller هو اللي بيدير دورة الحياة. كمان لو بتشغّل CLI tool داخل pod (مش server بيستقبل HTTP requests)، استخدم exec-based probe بدل httpGet، أو سيبهم خالص واعتمد على exit code.
وكمان: لو التطبيق بتاعك Singleton (نسخة واحدة بس)، Liveness Probe ممكن تضرّك أكتر ما تفيدك، لأن أي restart معناه downtime كامل بدون replicas تغطيه.
الخطوة التالية
افتح ملف الـ deployment.yaml بتاعك دلوقتي. لو الـ livenessProbe بيفحص /api/health اللي بيعمل query على الـ DB — افصلهم فورًا. اعمل /healthz يرجّع 200 ثابت بدون أي تبعيات، و/ready يفحص الـ DB والـ Redis. شغّل kubectl rollout restart deployment/<name> وراقب الـ restart count لمدة 24 ساعة بـ kubectl get pods -w. لو لقيت العدد نزل، إنت كسبت.
المصادر
- Kubernetes Documentation — Configure Liveness, Readiness and Startup Probes:
kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ - Kubernetes Documentation — Pod Lifecycle:
kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/ - CNCF Case Study (2024): "Optimizing Probe Configuration in Production Clusters"
- Google Cloud Architecture Center — Best practices for Kubernetes health checks:
cloud.google.com/architecture/best-practices-for-running-cost-effective-kubernetes-applications-on-gke - Tim Hockin (Kubernetes Co-Founder) — KubeCon EU 2023 talk: "The Anatomy of a Probe"
- Kubernetes Enhancement Proposal (KEP-950): Startup Probe —
github.com/kubernetes/enhancements