تخطيط السعة والتوسع التلقائي

التوسع القائم على قوائم الانتظار والأحداث

18 دقيقة الدرس 6 من 27

التوسع القائم على قوائم الانتظار والأحداث

يقوم Kubernetes HPA بالتوسع استناداً إلى وحدة المعالجة المركزية والذاكرة — وهي إشارات تقيس العمل الجاري معالجته حالياً. أما في أعباء العمل المدفوعة بالأحداث، فالإشارة الأهم فعلياً هي العمل المعلّق الذي لم تتم معالجته بعد: عمق موضوع Kafka، طول قائمة RabbitMQ، تأخر مجموعة مستهلكي SQS. وحدة المعالجة المركزية والذاكرة مؤشرات متأخرة هنا؛ أما عمق القائمة فهو المؤشر المتقدم. يسد KEDA (منسق Kubernetes المدفوع بالأحداث) هذه الثغرة بتوصيل المقاييس الخارجية العشوائية مباشرةً في آلية HorizontalPodAutoscaler الخاصة بـ Kubernetes. وقد تبرع به لـ CNCF عام 2020 وأصبح الآن متخرجاً من CNCF — وتدعمه جميع السحابات الكبرى والبيئات المحلية.

كيف يعمل KEDA: البنية الداخلية

يثبّت KEDA مكونين في مجموعتك. يراقب مشغّل KEDA موارد ScaledObject وScaledJob المخصصة ويترجمها إلى كائنات HorizontalPodAutoscaler الأصيلة في Kubernetes — فهو لا يتجاوز HPA، بل يقوده. أما محوّل المقاييس فهو تطبيق لواجهة برمجة external.metrics.k8s.io في Kubernetes: يستطلع مصدرك الخارجي (Kafka، Redis، SQS، Prometheus، Azure Service Bus، …) على فترات قابلة للضبط ويعرض قيمة المقياس حتى يتمكن HPA من التصرف بناءً عليها كأي مقياس آخر.

يهم هذا التصميم: لا يزال kubectl get hpa يُظهر وحدة التحجيم التي يديرها KEDA مع نوع المقياس EXTERNAL. تنطبق RBAC القياسية في Kubernetes، وPodDisruptionBudgets، وحدود minReplicas/maxReplicas كلها. يضيف KEDA قدرتَي التوسع إلى صفر (لا يستطيع HPA النزول دون 1 بشكل أصيل) والتوسع من صفر — عندما لا توجد رسائل، تنخفض النشرة إلى 0 نسخ وتقوم حلقة استطلاع KEDA باستيقاظها عند وصول الرسالة الأولى.

KEDA architecture and scaling flow External Sources Kafka / MSK RabbitMQ AWS SQS Redis Streams Prometheus KEDA (keda-system) Metrics Adapter external.metrics.k8s.io API KEDA Operator Watches ScaledObject CRDs HPA (managed) EXTERNAL metric type Workload Deployment Pod (replica 1) Pod (replica 2) Pod (scale-out) 0 replicas (idle)
يستطلع KEDA المصادر الخارجية عبر محوّل المقاييس ويقود HPA الأصيل في Kubernetes — بما في ذلك التوسع إلى صفر.

تثبيت KEDA

Helm هو مسار التثبيت القياسي. يعمل KEDA في مساحة الاسم keda الخاصة به ويسجّل امتداد واجهة برمجة خادم المقاييس. ثبّت الإصدار في بيئة الإنتاج — يتوافق إصدار الـ chart 2.x مع مشغّل KEDA 2.x (يتتبعان بعضهما).

helm repo add kedacore https://kedacore.github.io/charts helm repo update helm install keda kedacore/keda \ --namespace keda \ --create-namespace \ --version 2.14.0 \ --set prometheus.metricServer.enabled=true \ --set prometheus.operator.enabled=true # التحقق من تشغيل جميع حاويات KEDA الثلاث kubectl get pods -n keda # NAME READY STATUS RESTARTS # keda-operator-6c9b7d8f9c-x4pvk 1/1 Running 0 # keda-operator-metrics-apiserver-xxx 1/1 Running 0 # keda-webhooks-xxx 1/1 Running 0

التوسع بناءً على تأخر مستهلكي Kafka

حالة الاستخدام النموذجية لـ KEDA على نطاق واسع: مجموعة مستهلكي Kafka تعالج الأحداث لديها قسمات متأخرة. تريد نسخاً متناسبة مع إجمالي التأخر عبر القسمات، بهدف تأخر 1,000 رسالة لكل نسخة — لذا عند 50,000 رسالة غير معالجة تتوقع ~50 نسخة.

# ScaledObject لنشرة مستهلك Kafka apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: order-processor-scaler namespace: payments spec: scaleTargetRef: name: order-processor # النشرة المراد توسيعها pollingInterval: 15 # الفحص كل 15 ث (الافتراضي 30) cooldownPeriod: 60 # انتظر 60 ث بعد آخر حدث تقليص minReplicaCount: 2 # لا تنزل دون 2 (للإبقاء دافئاً؛ 0 = توسع إلى صفر) maxReplicaCount: 80 # سقف صارم يتوافق مع ميزانية العقد advanced: restoreToOriginalReplicaCount: false horizontalPodAutoscalerConfig: behavior: scaleUp: stabilizationWindowSeconds: 30 # توسع سريع policies: - type: Percent value: 100 periodSeconds: 30 scaleDown: stabilizationWindowSeconds: 300 # تقليص بطيء (5 دقائق) triggers: - type: kafka metadata: bootstrapServers: kafka-brokers.kafka.svc:9092 consumerGroup: order-processor-group topic: orders.created lagThreshold: "1000" # هدف الرسائل لكل نسخة offsetResetPolicy: latest sasl: plaintext tls: enable authenticationRef: name: kafka-trigger-auth # TriggerAuthentication مرجع إلى Secret
حسابات lagThreshold: يحسب KEDA desiredReplicas = ceil(totalLag / lagThreshold). مع 47,300 رسالة وعتبة 1,000 تحصل على ceil(47.3) = 48. هذا حتمي وسهل التفكير فيه خلال مراجعات الحوادث.

التوسع بناءً على عمق قائمة SQS

SQS هي المشغّل الأكثر شيوعاً في البيئات التي تعتمد AWS. يستخدم KEDA المشغّل aws-sqs-queue الذي يستدعي GetQueueAttributes لقراءة ApproximateNumberOfMessages. تحتاج إلى TriggerAuthentication أو تعليق IRSA — يفضّل IRSA في EKS لتجنب بيانات اعتماد طويلة الأمد في Secrets.

# TriggerAuthentication باستخدام IRSA (هوية حاوية EKS) apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: sqs-trigger-auth namespace: processing spec: podIdentity: provider: aws-eks # يستخدم تعليق IRSA الخاص بالحاوية --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: image-resize-scaler namespace: processing spec: scaleTargetRef: name: image-resizer minReplicaCount: 0 # توسع حقيقي إلى صفر: لا تكلفة عند الخمول maxReplicaCount: 200 pollingInterval: 20 cooldownPeriod: 120 triggers: - type: aws-sqs-queue metadata: queueURL: https://sqs.us-east-1.amazonaws.com/123456789012/image-resize queueLength: "50" # رسائل لكل نسخة awsRegion: us-east-1 identityOwner: operator authenticationRef: name: sqs-trigger-auth

ScaledJob لأعباء العمل الدُّفعية

للمهام التي تعمل حتى الاكتمال (ترميز الفيديو، استدلال ML الدُّفعي، توليد التقارير) استخدم ScaledJob بدلاً من ScaledObject. ينشئ KEDA Job جديداً في Kubernetes لكل وحدة عمل حتى maxReplicaCount، ثم ينظف المهام المكتملة. هذا يتجنب مشكلة القطيع الرعدي حيث يعيق مستهلك واحد طويل الاستطلاع الرسائل اللاحقة.

ScaledJob مقابل ScaledObject: استخدم ScaledObject لعمليات المستهلكين طويلة التشغيل (نشرة عامل Kafka العادية). استخدم ScaledJob عندما تُعيَّن كل رسالة لمهمة منفصلة محدودة — خاصةً إذا كان وقت المعالجة متغيراً للغاية. توفر المهام موازاة أفضل للتوزيع وتنظيفاً تلقائياً.

أنماط الفشل في الإنتاج والتخفيفات

يُظهر KEDA على نطاق واسع عدة أنماط فشل غير بديهية يجب مراعاتها قبل الانتقال إلى الإنتاج:

  • تعطل محوّل المقاييس يُعيد الضبط إلى نسخة واحدة: إذا أصبح خادم مقاييس KEDA غير متاح، لا يستطيع HPA جلب المقياس الخارجي ويعود إلى القيمة المعروفة الأخيرة — التي قد تكون قديمة. صمّم مستهلكك ليكون قابلاً للتكرار الآمن واحتفظ بالموضوع لفترة تغطي نافذة إعادة تشغيل KEDA.
  • زمن انتظار البدء البارد عند التوسع من صفر: الانتقال من 0 إلى 1 نسخة يستغرق وقتاً: الجدولة، سحب الصورة (إذا لم تكن مؤقتة)، وبدء تشغيل تطبيقك. خلال تلك الفجوة تتراكم الرسائل. للمسارات الحساسة للتأخر أبقِ minReplicaCount: 1 وتقبّل تكلفة الخمول.
  • سقف عدد القسمات: لا يمكن لـ Kafka توسيع المستهلكين فوق عدد القسمات. 10 قسمات = 10 مستهلكين متوازيين كحد أقصى بصرف النظر عن التأخر. وسّع القسمات قبل أن تحتاجها — زيادة قسمات Kafka لا رجعة فيها وتتطلب إعادة توازن.
  • حذف ScaledObject يحذف HPA: KEDA يمتلك كائن HPA. إذا حذفت ScaledObject أثناء حادث لإيقاف التوسع التلقائي، يُحذف HPA أيضاً وتنخفض نشرتك فوراً إلى عدد النسخ الأساسي. استخدم kubectl scale deployment للتجاوز اليدوي بدلاً من حذف ScaledObject.
  • تدوير Secret للمصادقة على المشغّل: إذا تمت إعادة تدوير Secret المشار إليه في TriggerAuthentication وخزّن KEDA القيمة القديمة، سيفشل التوسع بصمت. راقب سجلات مشغّل KEDA بالمقياس keda_scaler_errors_total وأنشئ تنبيهاً عند أي معدل غير صفري.
لا تضبط maxReplicaCount دون حسابات ميزانية العقد. سيطلب KEDA بكل سعادة 500 حاوية. إذا لم يستطع Cluster Autoscaler أو Karpenter توفير العقد بسرعة كافية، تبقى الحاويات في حالة Pending وتتراكم الرسائل. اربط دائماً maxReplicaCount بميزانية العقد التي تناولتها في الدرس 5، وضع ResourceQuota على مساحة الاسم كسقف صارم.

المراقبة لوحدات تحجيم KEDA

يعرض KEDA مقاييس Prometheus من محوّل المقاييس. استطلع خدمة keda-operator-metrics-apiserver على المنفذ 8080. المقاييس الرئيسية للتنبيه عليها:

  • keda_scaler_metrics_value — قيمة المقياس الخارجي الحالية (عمق القائمة، التأخر). ارسم هذا بجانب عدد النسخ للتحقق من استجابة وحدة التحجيم.
  • keda_scaler_errors_total — أي معدل غير صفري يعني أن المشغّل لا يمكنه قراءة مصدره. نبّه فوراً.
  • keda_scaled_object_paused — يُضبط على 1 عند إيقاف ScaledObject مؤقتاً (مفيد خلال نوافذ الصيانة).

على نطاق Google، الممارسة القياسية هي نشر لوحة Grafana لكل ScaledObject تُظهر: اتجاه عمق القائمة، عدد النسخ عبر الوقت، تعليقات أحداث التوسع، وإنتاجية المستهلك (رسائل/ثانية معالجة). هذه اللوحة هي أداتك الأساسية خلال مراجعات السعة (الدرس 9) والاستجابة للحوادث.