هذا المقال يتطلب مستوى محترف.
لو فاتورة EKS الإنتاج بتاعتك بتعدّي 4,200$ شهرياً وعندك Cluster Autoscaler شغّال، انت بتدفع ضريبة scheduler بطيء وغير اقتصادي. Karpenter بياخد قرار scale-up في 38 ثانية بدل 4 إلى 8 دقايق، وبيختار instance types بسعر spot الأنسب لكل workload تلقائياً. هنا تشوف ازاي تنقل من Cluster Autoscaler لـ Karpenter بـ NodePool واحد، وتوفّر بين 38% و 62% من فاتورة الـ compute.
Karpenter — Scheduler ذكي لـ EKS بدل Cluster Autoscaler
المشكلة باختصار
Cluster Autoscaler (اختصاراً CA) بيشتغل على مستوى الـ Auto Scaling Group. لو في Pod محتاج node جديد، CA بيدور على ASG مناسب ويزوّد instance من نوع محدّد سلفاً. النتيجة: لو الـ Pod محتاج 2 vCPU و 4GB RAM فقط، CA ممكن يرفعلك m5.2xlarge فيها 8 vCPU و 32GB، لأن ده اللي محدّد في الـ ASG. الباقي بتدفعه ومش بيتستخدم.
الأسوأ: متوسط زمن السكال-أب في CA على EKS بيوصل 4 دقايق، بين trigger الـ ASG و launch الـ instance و kubelet bootstrap و Pod scheduling. لو شغلك بيحصل فيه burst مفاجئ زي Black Friday أو إشعار push fan-out، أول 4 دقايق ممكن العملاء يشوفوا 503.
الفكرة الأساسية بمثال بسيط
تخيّل مطعم. الكاشير القديم (CA) عنده 3 طاولات بحجم 8 كراسي ثابت. لو دخلوا 4 عملاء بس، طاولة الـ 8 كاملة محجوزة وانت بتدفع إيجارها كاملاً. الكاشير الجديد (Karpenter) عنده مخزن طاولات بأحجام متنوعة (2 و 4 و 6 و 8)، وبيختار الحجم الصح للعدد الفعلي اللي دخل دلوقتي.
تقنياً: Karpenter بيتجاوز فكرة الـ Node Group/ASG كلياً. بيتعامل مع EC2 Fleet API مباشرة، وبيختار instance type من ضمن مئات الخيارات بناءً على:
- الـ Pod resources الفعلية (CPU/RAM/GPU)
- الـ topology constraints (zones, instance families)
- السعر اللحظي (On-Demand مقارنةً بـ Spot)
- فرص الـ consolidation: دمج Pods على عدد أقل من الـ nodes
NodePool واحد بدل 8 Node Groups
ده NodePool شغّال على Karpenter v1.0 و EKS 1.30. بيغطّي معظم الـ workloads العامة بدون ما تضطر تعمل 8 Node Groups مختلفة:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
- key: karpenter.k8s.aws/instance-cpu
operator: In
values: ["2", "4", "8", "16"]
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
limits:
cpu: 1000
memory: 4000Gi
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30s