KEDA بالعربي: scale-to-zero للـ Workers ووفّر 30% من فاتورة Kubernetes
لو عندك worker بيقرأ من Kafka ومحتفظ بـ 3 replicas طول الوقت حتى الساعة 4 الفجر لما ميكونش فيه رسايل، أنت بتدفع مقابل CPU فاضي. KEDA بيحل ده بإنه ينزّل الـ replicas لـ 0 لما الـ queue تفضى، ويرجّع يفتح Pods جديدة في ثواني أول ما يجي event. النتيجة الواقعية: تقليل 30% من تكلفة الـ compute على workloads غير متصلة بالـ HTTP requests.
المشكلة باختصار
الـ Horizontal Pod Autoscaler (HPA) الافتراضي في Kubernetes بيعتمد على CPU وMemory كـ signal. الـ signal ده بيفشل في حالتين شائعتين:
- Queue Workers: الـ CPU ممكن يفضل 15% والـ Kafka lag يوصل لـ 80 ألف رسالة. المستهلك بطيء لأن عدده قليل، مش لأنه مختنق.
- Idle Services: الـ HPA الحد الأدنى عنده
minReplicas: 1، يعني ممنوع ينزل تحت pod واحد حتى لو الخدمة فاضية ساعات.
KEDA بيحل الاتنين معًا: بيقرأ الـ signal من مصدر الأحداث مباشرة (Kafka, SQS, RabbitMQ, Redis, Prometheus…) وبيدي صلاحية النزول لـ 0.
ابدأ بمثال مبسّط: الكاشير في السوبر ماركت
تخيّل إنك مدير سوبر ماركت. عندك 3 كاشيرز واقفين من 8 الصبح لـ 12 بالليل. في الساعة 3 الفجر كاشير واحد كافي جدًا. في يوم العيد ممكن تحتاج 8. الـ HPA بيقيس "إزاي الكاشير تعبان" (CPU)، لكن المقياس الحقيقي هو طول الطابور قدامه.
KEDA بيشوف الطابور نفسه (عدد الرسايل في Kafka، عدد الـ messages في SQS). لو الطابور فاضي: صرف كل الكاشيرز لبيوتهم. لو الطابور زاد: افتح كاشيرز جداد. الفرق ده هو اللي بيخلّيه يوفر فلوس فعلاً.
المفهوم العلمي: إزاي KEDA بيشتغل تحت الكابوت
KEDA مش بديل للـ HPA، ده طبقة فوقه. لمّا تعمل ScaledObject، KEDA بيعمل الآتي:
- الـ KEDA Operator بيعمل poll كل
pollingIntervalثانية (افتراضي 30) للمصدر الخارجي. - لو الـ metric اتجاوز الـ
lagThreshold، KEDA بيعمل Scale من 0 لـ 1. - بعد كده بيسلّم الدفة للـ HPA العادي اللي بيعمل scaling من 1 لـ
maxReplicaCountبناءً على نفس الـ metric المعروضة عبرexternal.metrics.k8s.io. - لو المصدر فضي لمدة
cooldownPeriod(افتراضي 300 ثانية)، KEDA بيرجع ينزّل من 1 لـ 0.
الافتراض: المستهلك عندك asynchronous ويقبل cold start بين 5 و 30 ثانية. لو الخدمة real-time بتستقبل HTTP requests، الكلام ده مش هيناسبك (هنرجعله في قسم "متى لا تستخدم").
إعداد عملي: ScaledObject لـ Kafka Consumer
بنفرض إن عندك deployment اسمه orders-worker بيستهلك من topic orders-events. نثبّت KEDA أولاً عن طريق Helm: