هذا المقال للمستوى المتوسط — مناسب لو عندك خبرة أساسية بـ Kubernetes (Pods، Deployments، Replicas) وعايز تحمي تطبيقك من downtime مفاجئ وقت الـ cluster maintenance أو الـ node upgrade.
لو الـ cluster بتاعك اتعمله node upgrade الفجر اللي فات، وتطبيقك راح من 3 replicas لـ 0 لمدة 47 ثانية، المشكلة مش في Kubernetes ولا في الـ Deployment. المشكلة إنك ما عرّفتش Pod Disruption Budget. السطور القادمة بتقولك إزاي تمنع ده بـ 6 أسطر YAML.
Pod Disruption Budget في Kubernetes: الحماية اللي بتنساها لما الـ cluster بيتحدّث
المشكلة باختصار
Kubernetes بيفرّق بين نوعين من الـ disruptions:
- Involuntary — node بيموت فجأة، hardware failure، kernel panic، حد فصل الكهربا في الـ rack.
- Voluntary — انت أو حد من فريقك بيعمل
kubectl drain، الـ cluster autoscaler بيقلّل nodes عشان يوفّر، أو الـ control plane بيعمل rolling upgrade.
الـ voluntary disruptions دي اللي بتحصل بانتظام في الإنتاج. ولو مفيش PDB معرّف، الـ scheduler حر يقتل كل الـ replicas في نفس اللحظة. الـ load balancer بيلاقي نفسه قدام صفر pods، والمستخدمين بيشوفوا 503.
مثال للمبتدئ — المطعم اللي شغّال 24 ساعة
تخيّل عندك مطعم وفيه 5 شيفات. القاعدة الذهبية: لازم يفضل على الأقل 2 شيف موجودين عشان المطبخ يقدر يطلّع طلبات. لو المدير قرر يدّي إجازة جماعية، مش هيقدر يبعت 4 منهم في نفس اليوم؛ لازم يعمل rotation. لو بعتهم كلهم، المطعم بيقفل، والزباين بيمشوا.
PDB هو نفس الفكرة بالظبط. انت بتقول لـ Kubernetes: "وانت بتعمل maintenance أو upgrade، خلّي بالك إن لازم يفضل عندي على الأقل X من الـ replicas شغّالين، مهما حصل."
التعريف العلمي الدقيق
Pod Disruption Budget هو Kubernetes resource في الـ API group policy/v1، بيحدّد الحد الأدنى للـ Pods الجاهزة (minAvailable) أو الحد الأقصى للـ Pods اللي مسموح تروح في نفس الوقت (maxUnavailable) أثناء الـ voluntary disruption.
الآلية الفعلية: الـ Eviction API في الـ kube-apiserver بتشيك على PDB قبل ما تسمح بأي eviction request. لو الـ budget هيتكسر، الـ API بترجع HTTP 429 Too Many Requests والـ kubectl drain بيستنى لحد ما الـ Deployment يطلع pod جديد على node تاني.
الحل العملي — 7 أسطر YAML بس
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: api