تخطَّ إلى المحتوى

🚀 شرح DevOps و CI/CD

استراتيجيات النشر: Rolling / Blue-Green / Canary

الدرس 25 من 29· ⏱ 4 دقائق قراءة

لماذا نحتاج استراتيجية نشر؟

درس النشر التلقائي (CD) شرح الفرق بين Continuous Delivery وContinuous Deployment، لكنه لم يجب عن سؤال مهم: كيف يستبدل خط الأنابيب النسخة القديمة بالجديدة دون أن يشعر المستخدم بانقطاع؟ الإجابة هي استراتيجية النشر — الخطة التي تحدد كيف تنتقل حركة المرور من الإصدار القديم إلى الجديد.

Rolling Update (التحديث المتدرج)

هذه الاستراتيجية الافتراضية في أدوات مثل Kubernetes: بدل استبدال كل النسخ القديمة دفعة واحدة، يستبدلها الـ Deployment نسخة (Pod) تلو الأخرى.

  • ينشئ عدداً محدوداً من النسخ الجديدة (maxSurge)
  • يوقف عدداً محدوداً من النسخ القديمة فقط بعد جهوزية النسخ الجديدة (maxUnavailable)
  • حركة المرور توجَّه فقط للنسخ الجاهزة (Ready) عبر الـ Service
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 6
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1   # أقصى عدد نسخ يمكن أن تكون غير متاحة أثناء التحديث
      maxSurge: 1          # أقصى عدد نسخ إضافية تُنشأ مؤقتاً فوق العدد الأصلي
# متابعة تقدّم التحديث
kubectl rollout status deployment/my-app

# التراجع فوراً للإصدار السابق عند اكتشاف مشكلة
kubectl rollout undo deployment/my-app

بلا توقف تام (Zero Downtime)، لكن أثناء فترة الانتقال يكون هناك خليط من الإصدار القديم والجديد يعملان معاً — لازم يكون التطبيق متوافقاً مع نفسه بين الإصدارين (backward compatible).

Blue-Green Deployment

هنا يوجد بيئتان متطابقتان بالكامل: Blue (الإنتاج الحالي) وGreen (الإصدار الجديد). يُنشر الإصدار الجديد كاملاً على Green، يُختبر بمعزل عن حركة المرور الحقيقية، ثم تُحوَّل كل حركة المرور دفعة واحدة من Blue إلى Green — عادة عبر تبديل إعدادات الموازن (Load Balancer) أو الـ Service.

# مثال مبسّط: تبديل selector في Kubernetes Service من blue إلى green
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
    version: green   # كان blue قبل التبديل
  ports:
    - port: 80
      targetPort: 3000
  • التبديل فوري، والتراجع (Rollback) بنفس السرعة — يكفي إعادة الـ selector إلى blue
  • يتطلب موارد مضاعفة مؤقتاً (بيئتان كاملتان تعملان معاً)
  • لا يوجد خليط بين إصدارين في نفس اللحظة أمام المستخدم، على عكس Rolling Update

Canary Deployment

استراتيجية أكثر حذراً: يُوجَّه جزء صغير من حركة المرور (مثلاً 5%) إلى الإصدار الجديد بينما تبقى البقية على القديم. إذا سارت الأمور جيداً (لا ارتفاع في الأخطاء، أداء طبيعي)، تُزاد النسبة تدريجياً حتى تصل 100%؛ وإذا ظهرت مشكلة، تُعاد كل حركة المرور للإصدار القديم فوراً.

# مثال مفاهيمي بموازن يدعم تقسيم الوزن بين نسختين
routes:
  - version: v1
    weight: 95
  - version: v2   # الإصدار الكناري (canary)
    weight: 5

يمكن أن يكون التقسيم على مرحلتين فقط (نسبة صغيرة للتجربة ثم الباقي دفعة واحدة) أو تدريجياً بخطوات متزايدة — الفرق بين النهجين هو مقدار الحذر المطلوب.

مقارنة الثلاث استراتيجيات

المعيارRolling UpdateBlue-GreenCanary
توقف الخدمةلا يوجدلا يوجدلا يوجد
موارد إضافيةقليلة (نسخ إضافية مؤقتة)مضاعفة (بيئتان كاملتان)قليلة (نسبة صغيرة فقط)
سرعة التراجعمتوسطةفوريةفورية لنسبة محدودة فقط
خليط إصدارين أمام المستخدمنعم، أثناء التحديثلانعم، بنسبة محدودة ومتحكَّم بها
الأنسب لـتحديثات روتينية بلا مخاطر عاليةإصدارات كبيرة تحتاج تراجعاً فورياً مضموناًميزات حساسة تحتاج تحقق تدريجي من الأثر الحقيقي

⚠️ Canary تحتاج مراقبة (Monitoring) فعلية تراقب معدل الأخطاء واستجابة النظام تلقائياً — بدونها تفقد كل قيمتها، لأنك ببساطة لن تعرف متى توقف التوسع أو تتراجع. راجع درس المراقبة والتنبيهات.

أي استراتيجية تختار؟

  • فريق صغير، تغييرات متكررة وقليلة المخاطر → Rolling Update كافية غالباً (وهي افتراضية في Kubernetes أصلاً)
  • إصدار كبير أو حساس يحتاج ضمان تراجع فوري وسريع → Blue-Green
  • ميزة جديدة تريد قياس أثرها الحقيقي على شريحة من المستخدمين قبل التعميم → Canary

لا تعارض بين الاستراتيجيات — كثير من الفرق تستخدم Rolling Update للتحديثات اليومية وتحتفظ بـ Blue-Green أو Canary للإصدارات الكبرى.

🎯 التالي: التخزين المؤقت والقطع الأثرية في GitHub Actions

شرح استراتيجيات النشر: Rolling / Blue-Green / Canary — DevOps و CI/CD بالعربي
استراتيجيات النشر: Rolling / Blue-Green / CanaryDevOps و CI/CD بالعربي · The Code Fix

هل كان هذا الدرس مفيدًا؟