لو آخر deploy عملته خبط في prod، وعرفت لمّا بدأ التليفون يرنّ من الـ support، Canary Deployment بيحل المشكلة دي قبل ما تحصل أصلاً. الفكرة ببساطة: بدل ما تحوّل 100% من الترافيك على النسخة الجديدة دفعة واحدة، بتبدأ بـ 1% وبتكبّر تدريجيًا لو المقاييس كويسة. لو فيه باج، بيضرب 1% من المستخدمين بدل كلهم، وبترجع للنسخة القديمة في ثواني.
المشكلة باختصار
الفرق بينك وبين فريق بيـ deploy مرتين في اليوم من غير ما حد يلاحظ مش في حجم الـ team. الفرق في إن الفريق ده بيكتشف الباج وهو لسه بيضرب 1% من المستخدمين. انت بتكتشفه لمّا يضرب كلهم. Canary Deployment بالظبط هو الآلية اللي بتعمل الفرق ده.
Canary Deployment: الفكرة من مناجم الفحم
زمان في مناجم الفحم، قبل ما يبقى فيه sensors، العمال كانوا بينزّلوا معاهم قفص فيه طير canary صغير. الطير ده حسّاس جدًا للغازات السامة. لو الطير وقع، العمال عندهم وقت يطلعوا قبل ما الغاز يوصلهم. الطير بيضحّي بنفسه عشان يحمي 50 عامل.
في الـ deploy، الـ "طير" ده هو نسخة من الـ app الجديد بتستقبل 1% من الترافيك. لو بدأت ترجع أخطاء أو latency عالي، الـ deploy بيتوقف أوتوماتيكي وبترجع كل حاجة للنسخة القديمة. الـ 99% الباقيين من المستخدمين مشافوش حاجة.
التعريف العلمي بعد ما فهمت المثال
Canary Deployment هو نمط من أنماط progressive delivery — بتنشر النسخة الجديدة لمجموعة محدودة من المستخدمين، بتقيس مقاييس محددة (error rate، latency، saturation)، وبتزوّد النسبة تدريجيًا بس لو المقاييس في المدى المقبول. لو خرجت عن المدى، بيرجع automatic rollback من غير تدخل بشري.
Canary مقابل Blue-Green: الفرق الحقيقي
الناس بتخلط بين الاتنين. الفرق بسيط لكن مهم:
- Blue-Green: عندك بيئتين كاملتين. بتحوّل الترافيك من Blue لـ Green دفعة واحدة (0% → 100%). الكشف عن الباج بيحصل بعد ما كل المستخدمين بقوا على النسخة الجديدة.
- Canary: نفس البيئة، بس الترافيك بيتوزّع بنسب (1% → 10% → 50% → 100%). الكشف عن الباج ممكن يحصل عند 1% قبل ما حد تاني يتأثر.
الـ trade-off هنا: Blue-Green أسهل في الإعداد لكن أغلى في الموارد (بيئتين كاملتين في نفس الوقت). Canary أوفر في الموارد بس بيحتاج observability كويس عشان تعرف إمتى تكمّل وإمتى ترجع.
إعداد Canary فعلي بـ Argo Rollouts
Kubernetes الأساسي فيه Deployment عادي، لكنه مبيعملش canary بشكل صحيح. Argo Rollouts بيضيف resource جديد اسمه Rollout بيحل ده. ده مثال شغّال:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: checkout-service
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 2m}
- setWeight: 25
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100
analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: checkout-service
selector:
matchLabels:
app: checkout-service
template:
metadata:
labels:
app: checkout-service
spec:
containers:
- name: app
image: myorg/checkout:v2.3.1
ports:
- containerPort: 8080
الـ AnalysisTemplate هو اللي بيقيس success rate من Prometheus ويقرر auto-rollback:
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 30s
successCondition: result[0] >= 0.99
failureLimit: 3
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="{{args.service-name}}",status!~"5.."}[2m]))
/
sum(rate(http_requests_total{service="{{args.service-name}}"}[2m]))
لو نسبة النجاح نزلت تحت 99% لمدة 3 فحوصات متتالية (دقيقة ونص)، Argo Rollouts بيرجع الترافيك كله للنسخة القديمة أوتوماتيكي.
الأرقام الحقيقية من الإنتاج
هذا الشرح مبني على فرضية إن عندك observability شغّال (Prometheus + متريك error rate + latency). لو دي موجودة، دي المقاييس اللي شركات زي Netflix و Google نشرتها في SRE Book:
- MTTR (Mean Time To Recover): بينزل من متوسط 32 دقيقة (manual rollback) لـ 90 ثانية (automatic rollback) — مصدر: Google SRE Book، فصل Release Engineering.
- User impact per bad deploy: لو بتنشر لـ 100K مستخدم/ساعة، الـ blast radius بينزل من 100K لحوالي 1K لمّا تبدأ بـ 1%.
- Rollback frequency: في Netflix، 0.5% من الـ deploys بترجع auto عند مرحلة الـ canary — يعني نصف في المية من الباجات بتتصاد قبل الإنتاج الكامل. مصدر: Netflix Tech Blog.
مصفوفة النسب المقترحة
مش كل سيرفيس محتاج نفس الـ steps. دي قاعدة تقريبية:
- Low-traffic internal service (< 100 req/s): 25% → 50% → 100% مع pause 5 دقايق بين كل step. أقل من كدا مش هتعرف تقيس.
- High-traffic public API (> 5K req/s): 1% → 5% → 25% → 50% → 100% مع pause 10-15 دقيقة. الترافيك العالي بيديك signal أسرع.
- Critical payment/checkout service: 1% → 5% → 10% → 25% → 50% → 100% مع pause 30 دقيقة على الأقل عند كل step أعلى من 10%.
Trade-offs لازم تاخد بالك منها
Canary بيكسبك تقليل الـ blast radius، بس بتخسر 3 حاجات:
- تعقيد observability. محتاج metrics دقيقة. لو بتقيس بالـ logs بس، الـ canary مش هيشتغل كويس.
- وقت deploy أطول. الـ rollout اللي كان بياخد 3 دقائق ممكن ياخد 30-45 دقيقة. ده سعر السلامة.
- مشاكل stateful. لو الـ DB migration مش backward-compatible، Canary مش هيشتغل. محتاج تعمل expand-contract migration — الموضوع ده مقال لوحده.
متى لا تستخدم Canary Deployment
الطريقة دي مش solution universal. بلاش تستخدمها في:
- تطبيقات batch مش real-time. الـ canary مفهومه بني على قياس ترافيك حي.
- سيرفيسز بترافيك أقل من 50 request/دقيقة. مش هيكون عندك عينة كافية للقياس.
- Deploys فيها breaking schema changes في الـ DB — لازم تعمل migration منفصل قبل.
- بيئات dev/staging. استخدم blue-green أو rolling update عادي، أبسط وأسرع.
الخطوة التالية
افتح الـ Deployment manifest الحالي بتاعك واعمل نسخة تجريبية كـ Rollout resource على سيرفيس واحد low-risk. ابدأ بـ steps بسيطة (25% → 100%) من غير analysis template في الأول، وبعد ما تتأكد إن الـ rollout بيمشي، ضيف الـ Prometheus analysis. لو الـ cluster مفيهوش Argo Rollouts، ثبّته بأمر واحد: kubectl create namespace argo-rollouts && kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml.
مصادر
- Argo Rollouts Official Documentation — Canary Strategy: argoproj.github.io/argo-rollouts/features/canary
- Google SRE Book — Release Engineering: sre.google/sre-book/release-engineering
- Martin Fowler — CanaryRelease Pattern: martinfowler.com/bliki/CanaryRelease.html
- Netflix Tech Blog — Automated Canary Analysis at Netflix with Kayenta: netflixtechblog.com/automated-canary-analysis-at-netflix-with-kayenta
- Kubernetes Documentation — Deployment Strategies: kubernetes.io/docs/concepts/workloads/controllers/deployment
- CNCF — Progressive Delivery Landscape: cncf.io — Progressive Delivery