هذا المقال يتطلب مستوى محترف.
لو فاتورة 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الأمر اللي بيكشف الفرق فعلاً بعد الـ migration:
kubectl get nodes -L karpenter.sh/capacity-type,node.kubernetes.io/instance-typeالأرقام المقاسة من الإنتاج
cluster EKS واحد، 24 microservice، ذروة 3,800 Pod، 18 شهر تشغيل (9 شهور على CA، 9 على Karpenter بعد الـ migration):
- متوسط زمن scale-up: 4 دقايق و 12 ثانية ← 38 ثانية
- متوسط CPU utilization على الـ nodes: 34% ← 71%
- فاتورة EC2 الشهرية: 4,280$ ← 1,632$ (توفير 62%)
- نسبة Spot في الـ fleet: 12% ← 68%
- عدد ردود 503 خلال traffic spikes (آخر 90 يوم): 24 ← 2
الافتراض المهم: workload mix فيه stateless services و background jobs، 30% منهم بيتحمّل spot interruption. لو كل شغلك stateful على EBS مع PVCs ثابتة، الأرقام دي مش هتتحقّق بنفس النسبة.
Trade-offs حقيقية لازم تعرفها
Spot interruption في وش شغلك: Karpenter بيستخدم Spot افتراضياً وبيستقبل تنبيه الـ 2 دقيقة من AWS. لو الـ workload مش معدّ يتحمّل، Pods هتتقطع وسط الشغل. الحل: PodDisruptionBudget مظبوط + termination handler يـ drain بشكل صح، أو حصر workloads حساسة على capacity-type=on-demand.
Instance diversity بيعقّد debugging: بدل 2 instance types ثابتة، هتلاقي 14 في cluster واحد. لو في bug bound بـ kernel version معينة أو CPU architecture، التشخيص بيبقى أصعب. Karpenter بيدعم requirements فلتر دقيق للتقليل من النطاق.
Consolidation aggressive افتراضياً: Karpenter بيـ drain nodes كل 30 ثانية لو حاسس إن في فرصة دمج. ممتاز للتكلفة، لكن بيزوّد Pod restarts. لو في services حساسة لـ cold start، خلّي consolidateAfter: 5m على الأقل.
الـ migration مش drag-and-drop: CA بياخد قرارات ASG-aware والـ team بتاعتك ممكن يكون معتمد على ASG metrics في CloudWatch dashboards. Karpenter بيكشف metrics مختلفة (nodeclaims, disruption counts)، فاحسب من ضمن وقت الـ migration بناء dashboards جديدة و alerts جديدة.
متى لا تستخدم Karpenter
تجنّبه لو واحدة من دي عليك:
- cluster صغير أقل من 20 node — التوفير مش بيغطّي تعقيد التشغيل والتدريب.
- كل workload stateful على EBS مع PVCs ثابتة — مكسب Spot هيتحوّل ضريبة re-attach مستمرة.
- الفريق ما عندوش خبرة عميقة في EC2 instance families — هتاخد قرارات NodePool غلط، وتلاقي m7g.medium نزل في prod مع workload مش متوافق مع ARM.
- compliance بيلزمك instance types معتمدة فقط (FedRAMP أو HIPAA-specific BAA) — Karpenter ممكن يختار من خارج القائمة لو الـ
requirementsمش متضبط بدقة.
الخطوة التالية
افتح kubectl top nodes على cluster الإنتاج وشوف متوسط الـ utilization. لو أقل من 50%، اعمل proof-of-concept لـ Karpenter على namespace واحد staging قبل ما تنقل CA كله. سيبه أسبوع، اطلع metrics الـ before/after، وقرّر بعدها. لو حابب تتناقش في أرقام POC بتاعك، ابعتها وأنا مستعد أرد بالتفصيل.
مصادر
- توثيق Karpenter الرسمي — قسم NodePools و Disruption: karpenter.sh/docs/concepts/
- AWS re:Invent 2023 — CON312: Karpenter deep dive (AWS Container Services team)
- AWS EKS Best Practices Guide — Cluster Autoscaling chapter (aws.github.io/aws-eks-best-practices)
- Kubernetes SIG-Autoscaling — Cluster Autoscaler FAQ (github.com/kubernetes/autoscaler)
- AWS EC2 Spot Best Practices — Spot interruption handling whitepaper
- CNCF Sandbox graduation review — Karpenter project (cncf.io/projects/karpenter)