المستوى: متوسط. يفترض المقال إنك مرتاح مع YAML الأساسي في Kubernetes (Deployment, Service, Namespace) وعملت kubectl apply قبل كده. لو لسه في الأساسيات، روح للمقالات الأبسط الأول.
لو الـ cluster بتاعك عليه 4 replicas من API مهم، ويوم الـ node upgrade الـ kubectl drain صادف 3 nodes في نفس الدقيقة، 3 pods من الـ 4 ممكن يختفوا في نفس اللحظة. النتيجة: 503 يستمر 18 ثانية على عينك. PodDisruptionBudget بـ 8 سطور YAML بيمنع ده ويحفظ availability حقيقية وقت الترقية.
Pod Disruption Budget: درع الإتاحية في Kubernetes
المشكلة باختصار
Kubernetes بيفرّق بين نوعين من السقوط:
- Involuntary disruption: السيرفر مات، disk فضي، kernel panic. ده شغل replicas + topology spread.
- Voluntary disruption: انت طلبت
kubectl drainلتحديث الـ node، أو الـ cluster autoscaler بيمسح node لتوفير التكلفة، أو الـ node-pool بيتعمله rolling upgrade تلقائي من GKE/EKS.
الـ voluntary هو اللي PDB بيتدخل فيه. افتراضيًا، kubectl drain بيشيل كل pods في الـ node فورًا. مع 3 nodes متوازيين بيتعملوا drain في وقت واحد، ممكن 75% من replicas تختفي في 4 ثواني، وبيظهر 503 على المستخدم النهائي.
المثال البسيط — صيدلية الحي
تخيّل صيدلية فيها 4 صيادلة. لو المدير قرر يبعت 3 منهم في نفس اليوم لتدريب اختياري، الصيدلية تقريبًا بتقفل أمام الزبائن. الحل: قاعدة مكتوبة على الباب اسمها "بحد أقصى صيدلي واحد بيغيب في نفس اليوم". المدير لازم يلتزم بيها قبل ما يوقّع على إجازة.
في Kubernetes، الـ "مدير" هو الـ admin أو الـ autoscaler. الـ "صيدلي" هو الـ pod. PDB هو القاعدة المكتوبة. وقت ما الـ Eviction API يطلب يقتل pod، بيتأكد الأول إن العملية مش هتخالف الـ budget. لو هتخالفه، الـ eviction بيرفض بـ HTTP 429 ويستنى لحد ما الوضع يبقى آمن.
التعريف العلمي الدقيق
PodDisruptionBudget هو resource من نوع policy/v1 بيحدد واحد من اتنين:
minAvailable: الحد الأدنى من الـ pods الجاهزة (Ready) اللي لازم يفضل شغّال طول الوقت.maxUnavailable: الحد الأقصى من الـ pods اللي مسموح يكونوا غير جاهزين في نفس اللحظة.
القيم بتتحدد إما برقم مطلق (minAvailable: 3) أو نسبة مئوية (maxUnavailable: 25%). الـ selector بيحدد مجموعة الـ pods المعنية بنفس آلية labels في Deployment.
الآلية تقنيًا: الـ kubectl drain بيستخدم Eviction API (مش Delete API). قبل ما يوافق على الإخلاء، الـ kube-apiserver بيحسب: لو شيلت الـ pod ده، هيفضل عدد كافي من الـ pods الجاهزة؟ لو لأ، بيرفض الطلب بـ 429 TooManyRequests، والـ drain بيستنى ويعيد المحاولة كل ثانيتين بشكل افتراضي.