HPA استاندارد Kubernetes عمدتاً روی CPU و Memory فکر میکند. اما بسیاری از workloadها با صف پیام، عمق Kafka، نرخ HTTP، یا query دیتابیس زنده میمانند — نه با درصد CPU.
KEDA برای همین ساخته شد:
Kubernetes Event-driven Autoscaling — Application autoscaling made simple.
یعنی اسکیل هر کانتینر در Kubernetes بر اساس تعداد رویدادهایی که باید پردازش شوند — سبک، تکمنظوره، و کنار HPA بدون بازنویسی یا تداخل با بقیهٔ اپها.
CNCF Graduated. خاستگاه: Microsoft و Red Hat. سایت: keda.sh · Docs: docs · Repo: github.com/kedacore/keda · نیازمندی: Kubernetes ≥ 1.30
مشکل: اسکیل بدون سیگنال رویداد
بدون KEDA:
صف ۱۰۰٬۰۰۰ پیام → ۳ pod ثابت → backlog
شب صف خالی → ۳ pod بیکار → هزینه
HPA فقط روی CPU → صف پر ولی CPU پایین → اسکیل نمیشود
با KEDA:
queue depth / lag / cron / Prometheus ──► ScaledObject
│
├─ 0 → 1 (operator)
└─ 1 → N (HPA + external metrics)| معیار | HPA (CPU/Mem) | CronJob ثابت | Vendor APM scaler | KEDA |
|---|---|---|---|---|
| سیگنال رویداد | ضعیف | زمان | وابسته | ۷۰+ منبع |
| Scale-to-zero | نه (معمولاً) | نه | وابسته | بله (با trigger مناسب) |
| کنار HPA | خودش است | — | گاهی جایگزین | مکمل / مدیر HPA |
| Deployment + Job | Deployment | Job زمانبندی | وابسته | ScaledObject + ScaledJob |
| Vendor lock-in | کم | کم | بالا | آگنوستیک |
| CNCF | — | — | — | ✅ Graduated |
KEDA جایگزین HPA نیست — آن را با متریک خارجی تغذیه میکند و مسیر ۰↔۱ را خودش مدیریت میکند. برای معماری رویداد ببینید: CloudEvents. برای runtime اپ: Dapr.
KEDA چیست؟
- autoscaler مبتنی بر Kubernetes برای اسکیل بر اساس رویداد واقعی
- سبک؛ قابل افزودن به هر کلاستر بدون overwrite اجزای استاندارد
- صریحاً مشخص میکنید کدام اپ با KEDA اسکیل شود؛ بقیه دستنخورده میمانند
- پشتیبانی از Deployment، StatefulSet، Job و CRهایی که
/scaleدارند (مثل Argo Rollouts) - کاتالوگ ۷۰+ scaler برای cloud، messaging، DB، telemetry، CI/CD و …
- هدف پایداری: بهینهسازی scheduling و scale-to-zero برای کاهش مصرف منابع
قابلیتهای برجسته (از سایت)
| ویژگی | معنی |
|---|---|
| Autoscaling Made Simple | اسکیل غنی برای هر workload |
| Event-driven | واکنش به backlog واقعی، نه فقط infra |
| Built-in Scalers | ۷۰+ scaler آماده |
| Multiple Workload Types | Deployment / Job / CR با scale subresource |
| Reduce environmental impact | کمتر منابع بیکار |
| Extensible | External / community scalers |
| Vendor-Agnostic | AWS، Azure، GCP، on-prem، … |
| Azure Functions on K8s | اجرای و اسکیل Functions روی Kubernetes |
معماری: سه جزء، دو مسیر اسکیل
Event sources (Kafka, SQS, RabbitMQ, Prometheus, …)
│ poll / push
▼
┌─────────────────────────────────────────────┐
│ keda-operator │
│ • watch ScaledObject / ScaledJob │
│ • create/manage HPA │
│ • scale 0 ↔ 1 مستقیم │
├─────────────────────────────────────────────┤
│ keda-metrics-apiserver │
│ • external metrics → Kubernetes API │
│ • HPA از اینجا برای 1 ↔ N میپرسد │
├─────────────────────────────────────────────┤
│ keda-admission-webhooks │
│ • اعتبارسنجی ScaledObject هنگام apply │
│ • مثلاً دو ScaledObject روی یک target │
└─────────────────────────────────────────────┘
│
▼
HPA + ReplicaSet → Pods| مسیر | مسئول | بازه |
|---|---|---|
| Activation | keda-operator | ۰ → ۱ و ۱ → ۰ |
| Scaling | HPA + metrics-apiserver | ۱ → N و N → ۱ |
نتیجه: وقتی صف خالی است میتوانید واقعاً به صفر برسید؛ با اولین رویداد، operator اپ را بیدار میکند؛ بعد HPA بر اساس متریک خارجی تعداد را بالا میبرد.
محدودیت مهم CPU/Memory: با triggerهای CPU یا Memory، HPA متریک را از
metrics-serverمیگیرد نه از KEDA metrics API. بدون pod در حال اجرا متریکی نیست → scale-to-zero با CPU/Memory پشتیبانی نمیشود.
جزئیات: KEDA Concepts.
CRDهای اصلی
| CRD | کاربرد |
|---|---|
| ScaledObject | اسکیل Deployment / StatefulSet / CR دارای /scale |
| ScaledJob | ساخت Jobهای Kubernetes بر اساس رویداد (batch) |
| TriggerAuthentication / ClusterTriggerAuthentication | احراز هویت امن به منبع رویداد (Secret، IAM، AAD، …) |
از KEDA 2.0 به بعد Job از Deployment جدا شد (ScaledJob) و API group به keda.sh منتقل شد.
ScaledObject — اسکیل سرویسهای طولانیعمر
نمونهٔ مفهومی با RabbitMQ:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: rabbitmq-consumer
namespace: default
spec:
scaleTargetRef:
name: consumer-deploy # Deployment / StatefulSet / ...
pollingInterval: 30 # ثانیه — فاصلهٔ poll متریک
cooldownPeriod: 300 # بعد از idle، قبل از scale-to-zero
minReplicaCount: 0 # scale-to-zero
maxReplicaCount: 50
triggers:
- type: rabbitmq
metadata:
protocol: amqp
queueName: orders
mode: QueueLength
value: "5" # هدف: ~5 پیام per pod
authenticationRef:
name: rabbitmq-trigger-authفیلدهای کلیدی:
| فیلد | معنی |
|---|---|
scaleTargetRef | هدف اسکیل |
minReplicaCount / maxReplicaCount | کف و سقف |
pollingInterval | تناوب خواندن متریک |
cooldownPeriod | تأخیر قبل از رفتن به صفر |
triggers[] | یک یا چند منبع؛ ترکیب چند trigger مجاز است |
fallback | رفتار هنگام خطای scaler (در نسخههای جدید) |
ScaledObject با Prometheus
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: http-app-scaledobject
spec:
scaleTargetRef:
name: http-app
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus-server.default.svc:9090
threshold: "5"
query: sum(rate(http_requests_total{app="http-app"}[1m]))ScaledJob — batch بهجای replica ثابت
بهجای بالا بردن Deployment، برای هر backlog، Job میسازد (مثلاً یک Job به ازای پیام/دسته):
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: image-processor
spec:
jobTargetRef:
template:
spec:
containers:
- name: worker
image: example/image-processor:1.0
restartPolicy: Never
pollingInterval: 30
maxReplicaCount: 20
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 5
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.eu-west-1.amazonaws.com/123/images
queueLength: "1"
authenticationRef:
name: aws-trigger-authمناسب برای: پردازش تصویر، import، گزارش، کار ناهمگام یکبارمصرف. Jobهای تمامشده تمیز میشوند.
TriggerAuthentication
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-trigger-auth
namespace: default
spec:
secretTargetRef:
- parameter: host
name: rabbitmq-secret
key: hostالگوهای رایج auth:
| روش | مثال |
|---|---|
| Kubernetes Secret | connection string، password |
| Env / pod identity | workload با env از Secret |
| AWS IAM / IRSA / Pod Identity | SQS، Kinesis بدون کلید ثابت |
| Azure AD / Workload Identity | Service Bus، Event Hubs |
| GCP Workload Identity | Pub/Sub |
ClusterTriggerAuthentication همان ایده در سطح کلاستر برای اشتراک بین namespaceها.
کاتالوگ Scalerها (نمای کلی)
بیش از ۷۰ scaler در keda.sh/scalers — گروهبندی مفهومی:
| دسته | نمونهها |
|---|---|
| Messaging / Stream | Apache Kafka، RabbitMQ، NATS JetStream، ActiveMQ، Pulsar، IBM MQ، NSQ، Solace، Temporal |
| Cloud queues | AWS SQS / Kinesis / DynamoDB Streams، Azure Service Bus / Event Hubs / Storage Queue، GCP Pub/Sub / Cloud Tasks |
| Datastores | PostgreSQL، MySQL، MSSQL، MongoDB، Cassandra، Redis Lists/Streams، Elasticsearch، OpenSearch، etcd |
| Metrics / Observability | Prometheus، Datadog، New Relic، Dynatrace، Graphite، Loki، Splunk، CPU، Memory |
| Object storage | Azure Blob، GCS، OpenStack Swift |
| CI / runners | Azure Pipelines، GitHub Runner، Forgejo، Selenium Grid |
| زمان / عمومی | Cron، Metrics API، Kubernetes Workload / Resource، External، External Push |
| سایر | Azure Functions اکوسیستم، Predictkube (پیشبینی)، Elastic Forecast (experimental) |
External Scaler
اگر منبع شما در کاتالوگ نیست، scaler سفارشی (gRPC) یا External Push بنویسید. همچنین میتوان متریک خام scaler را با gRPC (RAW_METRICS_GRPC_PROTOCOL) به سیستمهای ثالث فرستاد — حالتهای all / hpa / pollinginterval.
HTTP Add-on و scale-to-zero برای وب
برای ترافیک HTTP خالص، KEDA هسته بهتنهایی interceptor ندارد. پروژهٔ HTTP Add-on (جدا، اغلب beta) درخواست را از یک interceptor رد میکند، متریک صف/همزمانی میسازد و با triggerهایی مثل external-push اپ را از صفر بیدار میکند.
| نکته | توصیه |
|---|---|
| محیط staging / dev بیکار | کاندید خوب برای scale-to-zero HTTP |
| production پرترافیک | interceptor میتواند bottleneck شود — با احتیاط و تست؛ بسیاری هنوز HPA+Prometheus یا minReplicas≥1 نگه میدارند |
| جایگزین | متریک Prometheus/Ingress روی ScaledObject بدون add-on (اغلب بدون صفر واقعی مگر صف/رویداد جدا) |
نصب
طبق Deploying KEDA:
Helm (رایجترین)
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda --create-namespace
kubectl get pods -n kedaYAML (کنترل کامل)
# با admission webhooks — نسخه را با آخرین release عوض کنید
kubectl apply --server-side -f \
https://github.com/kedacore/keda/releases/download/v2.20.0/keda-2.20.0.yamlسایر روشها
| روش | مناسب |
|---|---|
| Operator Hub / OLM | OpenShift و کلاسترهای OLM |
| MicroK8s | lab محلی (helm3 + dns) |
| CRD جدا | مدیریت lifecycle CRD خارج از chart |
حذف:
helm uninstall keda --namespace keda
# در صورت گیر کردن finalizer:
kubectl patch scaledobject <name> -p '{"metadata":{"finalizers":null}}' --type=mergeمقایسه کوتاه
| ابزار | تمرکز | Scale-to-zero رویداد | کاتالوگ trigger |
|---|---|---|---|
| HPA alone | CPU/Mem/custom metrics | محدود | وابسته به metrics pipeline |
| VPA | اندازهٔ request/limit | — | — |
| Cluster Autoscaler / Karpenter | تعداد Node | — | — |
| Knative Serving | request-driven + zero | قوی برای HTTP | مدل سرویس خاص |
| KEDA | event sources روی workload موجود | قوی (صف/متریک) | ۷۰+ |
KEDA اغلب کنار Cluster Autoscaler مینشیند: اول pod، بعد در صورت نیاز node. با Karmada میتوان ScaledObject را به چند کلاستر propagate کرد؛ با Helm و Flux نصب و سیاست را GitOps کرد.
عملیات و عیبیابی
| علامت | بررسی |
|---|---|
| اسکیل نمیشود | kubectl describe scaledobject؛ وضعیت trigger Active؟ |
| به صفر نمیرود | minReplicaCount، cooldownPeriod، آیا trigger هنوز «فعال» است؟ |
| از صفر برنمیگردد | activation threshold؛ دسترسی auth به صف؛ CPU-only trigger؟ |
| HPA ساخته نشده | webhook/operator log؛ تداخل دو ScaledObject روی یک target |
| نوسان (flapping) | pollingInterval، threshold، stabilization HPA |
| خطای auth | TriggerAuthentication و Secret/IAM role |
kubectl get scaledobject,scaledjob,hpa -A
kubectl logs -n keda deploy/keda-operator -f
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | headبرای observability مسیر اسکیل و latency اپ: Jaeger و Fluentd.
یکپارچگی با استک P30Light
| لایه | مقاله |
|---|---|
| رویداد | CloudEvents |
| App runtime | Dapr |
| GitOps / Package | Flux · Helm |
| Multi-cluster | Karmada |
| Mesh | Istio · Linkerd |
| Tracing / Logs | Jaeger · Fluentd |
الگوی رایج:
Queue / Stream / Cron / Prometheus
→ KEDA (ScaledObject|ScaledJob)
→ HPA + Pods
→ (اختیاری) Cluster Autoscaler / Karpenterخلاصه
| موضوع | جمعبندی |
|---|---|
| چیست | Event-driven autoscaler روی Kubernetes |
| وضعیت | CNCF Graduated؛ Microsoft + Red Hat |
| رابطه با HPA | مکمل؛ KEDA HPA را میسازد و متریک خارجی میدهد |
| ۰↔۱ / ۱↔N | operator / HPA |
| CRD | ScaledObject، ScaledJob، TriggerAuthentication |
| اکوسیستم | ۷۰+ scaler + External + HTTP Add-on |
| محدودیت | CPU/Memory alone → بدون scale-to-zero |
قدم بعدی
- با Helm در namespace
kedaنصب کنید و سه Deployment اپراتور را چک کنید. - یک consumer ساده + صف (RabbitMQ یا Redis) و ScaledObject با
minReplicaCount: 0بسازید. - صف را پر/خالی کنید و مسیر ۰↔۱↔N را با
kubectl get pods -wببینید. - برای batch، یک ScaledJob روی SQS/Kafka امتحان کنید.
- TriggerAuthentication را به IAM/Workload Identity وصل کنید — کلید در YAML نگذارید.
- قبل از production، cooldown، maxReplica و رفتار fallback را در load test قفل کنید.
منابع
- KEDA — سایت رسمی
- Concepts
- Deploying KEDA
- Scalers catalog
- HTTP Add-on
- GitHub — kedacore/keda
- Helm charts
منتشر شده در P30Light — بخش زیرساخت و سرور