النشر المتدحرج
النشر المتدحرج
يستبدل النشر المتدحرج (Rolling Deployment) نسخ الإصدار القديم بالإصدار الجديد بشكل تدريجي — دفعة واحدة في كل مرة — بحيث لا يكون التطبيق غير متاح بالكامل في أي وقت. إنه استراتيجية النشر الافتراضية في Kubernetes وAmazon ECS ومعظم منصات الحوسبة المُدارة، لأنه يحقق نقطة توازن عملية: صفر توقف، أقل قدر من الضرر للإصدار السيئ، ولا حاجة لبنية تحتية مضاعفة (على عكس النشر الأزرق-الأخضر).
فهم الآليات بعمق — ليس فقط المسار السعيد — هو ما يُميّز المهندسين الذين يُهيّئون النشر المتدحرج عن أولئك القادرين على تشغيله بأمان في الإنتاج.
الآليات: Surge وUnavailable وحجم الدفعة
يتحكم معاملان في عملية التدحرج بأكملها. في Kubernetes يوجدان في قسم spec.strategy.rollingUpdate في مورد Deployment:
maxUnavailable— الحد الأقصى لعدد الـ pods (أو نسبة منreplicas) التي يمكن أن تكون أقل من الجاهزة في آنٍ واحد أثناء الطرح. ضبطها على0يعني: لا تقتل pod قديماً حتى يُؤكَّد أن الجديد سليم. هذا يحمي الطاقة الاستيعابية على حساب اشتراط وجود pod الـ"surge" الإضافي.maxSurge— الحد الأقصى لعدد الـ pods فوق عدد النسخ المطلوب التي يمكن أن توجد في آنٍ واحد. ضبطها على1يعني السماح لـ Kubernetes بتشغيلreplicas + 1pods مؤقتاً. وهكذا يُنشئ بأمان الـ pod الجديدة قبل إنهاء القديمة.
يتبادل الإعدادان خطر السعة مقابل السرعة. في أحد الطرفين، maxUnavailable: 25%, maxSurge: 0 يقتل ربع الـ pods أولاً ثم يملأها — سريع لكن بسعة منخفضة مؤقتاً. في الطرف الآخر، maxUnavailable: 0, maxSurge: 1 يُضيف دائماً قبل الإزالة — صفر خسارة في السعة لكن يستخدم عقداً إضافية مؤقتاً. تختار معظم أنظمة الإنتاج نقطة وسطى بناءً على هامش الموارد المتاح ومتطلبات الـ SLO.
maxUnavailable + maxSurge كلاهما صفراً — هذا يجعل التقدم مستحيلاً. يتحقق Kubernetes من ذلك ويرفض مثل هذا الإعداد. الإعدادات الافتراضية (maxSurge: 25%, maxUnavailable: 25%) معقولة للخدمات عديمة الحالة لكنها تحتاج ضبطاً لأي شيء بمتطلبات توافرية صارمة.استنزاف الاتصالات: لماذا يهم
حين يُعلّم Kubernetes pod للإنهاء، يُزيله فوراً من كل شرائح نقطة نهاية Service — تتوقف الاتصالات الجديدة عن التوجيه إليه. لكن الطلبات الجارية المتصلة بذلك الـ pod تُعالَج بالفعل. بدون الاستنزاف، تُوقَف تلك الطلبات بشكل مفاجئ في منتصفها.
الحل هو استنزاف الاتصالات، يتحقق عبر آليتين متعاونتين:
terminationGracePeriodSecondsعلى الـ pod — كم من الوقت ينتظر Kubernetes بعد إرسالSIGTERMقبل الإنهاء القسري بـSIGKILL. الافتراضي 30 ثانية. يجب أن يستمع تطبيقك لـSIGTERMويبدأ إيقاف تشغيل رشيق: يتوقف عن قبول اتصالات جديدة، يُنهي الطلبات النشطة، ثم يخرج بشكل نظيف.- خطاف دورة الحياة
preStop— نوم قصير (عادةً 5–15 ثانية) يُحقن قبل وصولSIGTERMللحاوية. تُعالج هذه النافذة تأخر الانتشار بين إزالة نقطة النهاية من شرائحServiceوتحديث جميع عقد موازن الحمل الأعلى (kube-proxy، Envoy sidecars، cloud LB) لجداول اتصالاتها. بدون هذا النوم، لا تزال الطلبات الجارية في طبقة موازن الحمل تصل إلى الـ pod في الفجوة القصيرة بعد إزالة نقطة نهايته لكن قبل توقفه عن الاستماع.
preStop هو السبب الأكثر شيوعاً لأخطاء 502/504 أثناء النشر المتدحرج. تحديث شريحة نقطة النهاية وتدفق موازن الحمل ليسا فوريين — توجد نافذة انتشار من 1–15 ثانية تبعاً لحجم الكلاسترز ونوع الـ LB. المهندسون الذين يتخطون هذا يرون طرحاً نظيفاً في الاختبار (كلاسترز صغيرة، انتشار سريع) وانفجاراً من الأخطاء في الإنتاج (كلاسترز كبيرة، انتشار بطيء). أضف النوم دائماً.عملية التدحرج: مخطط خطوة بخطوة
يتتبع المخطط أدناه نشراً من 4 نسخ يتدحرج من v1 إلى v2 مع maxSurge: 1, maxUnavailable: 0. كل عمود يمثل دورة مصالحة واحدة في Kubernetes.
فحوصات الجاهزية: بوابة الأمان
لن يُزيل متحكم التدحرج pod قديماً حتى يجتاز الجديد فحص الجاهزية. هذه هي الآلية التي تجعل maxUnavailable: 0 ذات معنى. إذا كان فحص جاهزيتك خاطئاً — يمر دائماً، يفحص المسار الخاطئ، أو يستخدم initialDelaySeconds قصيراً جداً — فسيعتبر المتحكم pod يُقلع "جاهزاً" ويبدأ في سحب السعة قبل أن يستطيع الخدمة فعلياً معالجة الحركة.
في شركات التقنية الكبرى، تفحص فحوصات الجاهزية نقطة نهاية صحة عميقة تتحقق من اتصالية قاعدة البيانات، وقابلية الوصول للكاش، وحالة التبعيات الحيوية — لا مجرد "هل منفذ HTTP مفتوح". الـ pod الذي يُجيب على HTTP لكن لا يستطيع الوصول إلى قاعدة بياناته ليس جاهزاً لخدمة الحركة ويجب ألا يستقبلها.
مراقبة الطرح والتراجع
لا تُطلق نشراً متدحرجاً وتبتعد. استخدم kubectl rollout status لمتابعة الموجة مباشرة. اضبط موعداً نهائياً بـ spec.progressDeadlineSeconds — إذا لم يكتمل الطرح خلال تلك النافذة، يُعلّم Kubernetes النشر كمتوقف (يظهر كشرط DeadlineExceeded)، وهو ما يجب أن يُعامله نظام الـ CD كفشل ويُطلق التراجع.
النشر المتدحرج في ECS
يستخدم Amazon ECS مصطلحات مختلفة للمفاهيم ذاتها. minimumHealthyPercent يُقابل عكس maxUnavailable، وmaximumPercent يحدد سقف الـ surge. لخدمة ECS بـ 10 مهام، ضبط minimumHealthyPercent: 90, maximumPercent: 110 يُعادل maxUnavailable: 1, maxSurge: 1 في Kubernetes. يُهيَّئ استنزاف اتصالات موازن الحمل على مجموعة الهدف (deregistration_delay.timeout_seconds) — اضبطه ليُطابق أو يتجاوز مدة أطول طلب متوقع.
أنماط الفشل في الإنتاج وكيفية اكتشافها
تفشل عمليات النشر المتدحرجة بأنماط يمكن التنبؤ بها. معرفتها مسبقاً يسمح لك بالأدوات الرصدية قبل النشر، لا بعد الحادثة:
- تباين الإصدارات (Version Skew): أثناء التدحرج، يعملان v1 وv2 في آنٍ واحد. إذا كتب v2 عموداً في قاعدة البيانات لا يعرفه v1، أو غيّر شكل استجابة API يتوقعه مستدعٍ من v1، فلديك خطأ تباين. الدرس 8 (Expand-Contract) يُعالج هذا تحديداً — لا تنشر تغييرات المخطط وتغييرات التطبيق في نفس التدحرج.
- فحص الجاهزية البطيء: إذا احتاج تطبيقك 90 ثانية للإحماء لكن
initialDelaySecondsهو 10، سيعمل الفحص قبل أن يكون التطبيق جاهزاً، ويفشل، وسيُعيد الـ pod تشغيله في دورة CrashLoopBackOff. يتوقف الطرح. اضبطinitialDelaySecondsبسخاء واستخدمstartupProbeللتطبيقات ذات أوقات التشغيل المتغيرة. - شح الموارد أثناء الـ Surge: مع
maxSurge: 2على نشر بـ 10 نسخ تحتاج مؤقتاً لعقد لـ 12 pod. إذا كانت كلاستر موارده بالفعل عند 95%، ستكون pods الـ surge في حالةPendingوسيتوقف الطرح. يساعد Cluster Autoscaler لكن له كمون خاص به (1–3 دقائق لتوفير عقدة جديدة). حجّم كلاسترك بهامش 20–30% على الأقل للنشر المتدحرج. - تعارض PodDisruptionBudget (PDB): PDB بـ
minAvailable: 100%(أوmaxUnavailable: 0) سيتعارض مع Deployment بـmaxUnavailableيساوي 0 أيضاً — لا يستطيع متحكم الإخلاء إرضاء كلا القيدين وسيتوقف الطرح. نسّق بين إعدادات PDB وNशر التدحرج.
عمليات النشر المتدحرجة هي استراتيجية الحصان العملي للإصدارات الروتينية. لا تصلح للتغييرات الجذرية — استخدم feature flags (الدرس 5) أو blue-green (الدرس 3) حين لا يمكن للإصدارين القديم والجديد التعايش بأمان. لكل شيء آخر، نشر متدحرج جيد الضبط مع استنزاف مناسب، وفحوصات جاهزية دقيقة، وقاطع دائري هو الخيار الافتراضي الصحيح.