نشر الكناري يحوّل شريحة صغيرة من الحركة الحية إلى إصدار جديد وينتظر لمعرفة ما إذا كان هذا الإصدار يتصرف بقبول قبل المضي قُدُماً. كان قرار الترقية أو الإلغاء يعتمد على مهندس يحدق في لوحات المعلومات. تحليل الكناري الآلي يستبدل ذلك الإنسان بحلقة تحكم: وحدة تحكم تستعلم من منظومة المراقبة لديك بجدول زمني، وتُسجِّل الكناري مقابل سياسة، وتُرقّي أو تتراجع دون أن يضغط أحد على زر.
هذه هي الطريقة الفعلية التي تُشغِّل بها Uber وNetflix وGoogle SRE عمليات النشر على نطاق واسع. وحدة التحكم لا تثق في شارة CI خضراء — إنها تثق بإشارات الإنتاج الحية مقابل الخط الأساسي. عند تنفيذها بشكل صحيح، تلتقط التراجعات التي لا تستطيع اختبارات التكامل رؤيتها: ارتفاعات الكمون تحت أنماط الحركة الفعلية، زيادات معدل الأخطاء في مناطق جغرافية محددة، تسربات الذاكرة التي تظهر فقط تحت الحمل المستدام.
حلقة التحليل
كل نظام كناري آلي — سواء كان Argo Rollouts أو Flagger أو وحدة تحكم مخصصة — ينفذ نفس الحلقة الأساسية. فهمها بدقة هو المتطلب الأساسي لضبطها بشكل صحيح.
حلقة تحليل الكناري الآلي: وحدة تحكم Rollout تقسم الحركة، تُنشئ AnalysisRun يستعلم من موفري المقاييس في كل فترة، وتُرقّي أو تُلغي بناءً على اجتياز عتبات المقاييس.
تمر الحلقة بأربع مراحل في كل فترة: الانتظار (جمع بيانات كافية)، الاستعلام (جلب المقاييس من منظومة المراقبة)، التقييم (مقارنة الكناري مع الخط الأساسي وفق السياسة)، القرار (زيادة الوزن أو التوقف أو الإلغاء). عدد الفترات وزيادة الوزن لكل خطوة هما مقابس الضبط الأساسيين.
Argo Rollouts: الترقية القائمة على المقاييس
Argo Rollouts يوسّع Kubernetes بـ CRD اسمه Rollout يحل محل Deployment العادي. قسم استراتيجية الكناري يحدد أوزان الخطوات ويشير إلى AnalysisTemplate يحتوي على استعلامات المقاييس.
# analysis-template.yaml — AnalysisTemplate يستعلم من Prometheus
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: production
spec:
args:
- name: service-name
- name: canary-hash # يُحقنه Rollouts من pod-template-hash
metrics:
- name: success-rate
interval: 1m
count: 5 # 5 قياسات؛ يحتاج 4 من 5 للنجاح
successCondition: result[0] >= 0.99 # معدل نجاح 99% على الأقل
failureLimit: 1
provider:
prometheus:
address: http://prometheus.monitoring.svc:9090
query: |
sum(rate(http_requests_total{
job="api-service",
pod=~".*{{args.canary-hash}}.*",
status!~"5.."
}[2m]))
/
sum(rate(http_requests_total{
job="api-service",
pod=~".*{{args.canary-hash}}.*"
}[2m]))
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: p99-latency
namespace: production
spec:
metrics:
- name: p99-latency
interval: 1m
count: 5
successCondition: result[0] < 0.300 # p99 أقل من 300 مللي ثانية
failureLimit: 1
provider:
prometheus:
address: http://prometheus.monitoring.svc:9090
query: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{
job="api-service",
pod=~".*{{args.canary-hash}}.*"
}[2m])) by (le)
)
دائماً استعلم من بودات الكناري مباشرةً، وليس من الخدمة. استعلام Prometheus يضرب الخدمة بأكملها سيحسب متوسط بودات الكناري والثابتة معاً ويُخفي تراجعاً خطيراً. صفِّ بعلامة pod باستخدام pod-template-hash الذي يُحقنه Rollouts كمعامل. وبالمثل، حدّد نطاق مقاييس Datadog الخاصة بك بعلامة version أو rollouts_pod_template_hash.
Flagger: البديل الأصيل لـ Kubernetes
Flagger مشروع CNCF تُحافظ عليه Weaveworks. بدلاً من CRD اسمه Rollout، يستخدم CRD اسمه Canary يُغلِّف Deployment موجوداً — Flagger ينشئ ويدير كائنات Deployment الأساسية والكناري نيابةً عنك. هذا يجعل إضافته على كلاستر موجود أسهل دون إعادة هيكلة المانيفستات.
# flagger-canary.yaml — Flagger Canary resource wrapping a Deployment
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: api-service
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
progressDeadlineSeconds: 600
service:
port: 8080
targetPort: 8080
gateways:
- public-gateway.istio-system.svc.cluster.local
hosts:
- api.myorg.com
analysis:
interval: 1m # تقييم كل 60 ثانية
threshold: 5 # إلغاء بعد 5 فشل متتالي
maxWeight: 50 # لا تتجاوز 50% حركة كناري
stepWeight: 10 # زيادة 10% لكل خطوة ناجحة
metrics:
- name: request-success-rate
thresholdRange:
min: 99 # يتطلب معدل نجاح >= 99%
interval: 1m
- name: request-duration
thresholdRange:
max: 500 # يتطلب p99 <= 500 مللي ثانية
interval: 30s
webhooks:
- name: acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 30s
metadata:
type: bash
cmd: "curl -sd 'test' http://api-service-canary.production/healthz | grep OK"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 -c 2 http://api-service-canary.production/"
دائماً أوصِل حملاً اصطناعياً إلى الكناري أثناء التحليل. بدون حمل، تُعيد استعلامات Prometheus بيانات فارغة، وهو ما يعامله Flagger وArgo Rollouts على أنه نجاح افتراضي. استخدم webhook محمل Flagger أو مهمة k6 / hey منفصلة تضرب نقطة نهاية الكناري باستمرار خلال نافذة التحليل. لا تعتمد أبداً على حركة الإنتاج المحيطة وحدها — خاصةً في الخطوات المبكرة عندما يكون وزن الكناري 5-10% فقط.
اختيار المقاييس: ماذا تقيس
المقاييس التي تحللها هي أهم قرار تصميمي. استخدم هذا التدرج، مُرتباً حسب نسبة الإشارة إلى الضوضاء:
معدل أخطاء HTTP 5xx — الحد الأدنى. كناري يزيد معدل أخطاء الخادم من 0.1% إلى 2% يجب أن يفشل فوراً. قِسه كـ (الطلبات غير 5xx) / (إجمالي الطلبات) لتجنب القسمة على صفر عندما يكون الكناري بارداً.
شريحات كمون الطلب — p99 وp99.9 تلتقط تراجعات كمون الذيل التي يُخفيها متوسط الكمون. إصدار جديد يضاعف p99 مع إبقاء المتوسط كما هو سيُدهور تجربة 1% من المستخدمين — وهو ما يعني عند 100,000 طلب/ثانية 1,000 شخص في الثانية.
مقاييس الأعمال — للخدمات التي تواجه المستخدم: معدل بدء الدفع، معدل نجاح تسجيل الدخول، معدل النقر على نتائج البحث. هذه تلتقط تراجعات المنطق التي تُعيد 200 OK لكنها تحسب الإجابة الخاطئة.
إشباع الموارد — اتجاهات نمو CPU والذاكرة خلال نافذة التحليل. إصدار يبدو جيداً عند 10% من الحركة لكنه سيتعطل بسبب نفاد الذاكرة عند 100% قابل للاكتشاف مبكراً إذا تتبعت معدل نمو container_memory_working_set_bytes.
ميكانيكيات التراجع وأنماط فشل الإنتاج
عند فشل AnalysisRun، يحتاج كل من Argo Rollouts وFlagger إلى تصريف الكناري بنظافة. Argo Rollouts يضع وزن الكناري على 0، وينتظر حتى تنتهي الطلبات الجارية (يتحكم فيه progressDeadlineSeconds ومهلة تصريف شبكة الخدمة الخاصة بك)، ثم يُقلِّص ReplicaSet للكناري إلى 0. البودات الثابتة لم تتوقف عن الخدمة أبداً، لذا يعاني المستخدمون فقط من زيادة الكمون خلال نافذة الكناري — وليس انقطاعاً.
التحليلات غير الحاسمة هي نمط فشل صامت. إذا أعاد استعلام Prometheus بيانات فارغة (هدف الفحص معطل، خطأ في اسم المقياس، عدم تطابق التسمية)، يُصنِّف Argo Rollouts المقياس على أنه غير حاسم، لا فاشل. بشكل افتراضي، ثلاثة نتائج غير حاسمة متتالية تُلغي الطرح — لكن كثيراً من الفرق تُغيِّر هذه العتبة دون فهم الآثار. استعلام مُعطل يُعيد دائماً بيانات فارغة سيُلغي كل كناري للسبب الخاطئ، مما يجعل الفريق يفقد الثقة في النظام ويُعطِّله. دائماً اختبر استعلامات PromQL يدوياً في واجهة Prometheus قبل وضعها في AnalysisTemplate.
أهم عادة تشغيلية هي مراقبة kubectl argo rollouts get rollout api-service -w خلال نشر. هذا يبث تقدم الخطوات، ونتائج التحليل، والقيم الدقيقة للمقاييس التي قادت كل قرار نجاح/فشل — مما يجعل تحليلات ما بعد الحوادث واضحة عند إلغاء الكناري:
# مراقبة طرح حي (Argo Rollouts)
kubectl argo rollouts get rollout api-service -w -n production
# إجبار الترقية على تجاوز الخطوة الحالية (استخدم بحذر — يتجاوز التحليل)
kubectl argo rollouts promote api-service -n production
# إلغاء فوري والتراجع
kubectl argo rollouts abort api-service -n production
# سرد جميع AnalysisRuns لطرح (فحص قيم المقاييس لكل تشغيل)
kubectl get analysisrun -n production -l rollout=api-service \
--sort-by=.metadata.creationTimestamp
# وصف أحدث AnalysisRun للحصول على نتائج مقاييس تفصيلية
kubectl describe analysisrun \
$(kubectl get analysisrun -n production -l rollout=api-service \
-o jsonpath='{.items[-1].metadata.name}')
تحليل الكناري الآلي ليس حلاً سحرياً — إنه جيد بقدر المقاييس التي تُغذيه. الانضباط يكمن في تصميم عتبات ضيقة بما يكفي لالتقاط التراجعات الحقيقية، ومتساهلة بما يكفي لتحمّل تباين الحركة الطبيعي. ابدأ محافظاً (إلغاء عند زيادة معدل الخطأ 1%، زيادة p99 بـ 50 مللي ثانية)، اجمع البيانات على معدلات الإنذارات الكاذبة عبر عدة إصدارات، وشدِّد أو خفِّف استناداً إلى الأدلة. بعد أشهر قليلة من التحليل الجيد الضبط، يتوقف فريقك عن الخوف من عمليات نشر مساء الجمعة.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية