KEDA 2.21.0 est sorti le 23 septembre 2026. Ce composant open source, gradué par la CNCF, change la manière dont un cluster Kubernetes réagit à la charge réelle plutôt qu’à des métriques CPU ou mémoire approximatives. Ce tutoriel installe KEDA pas à pas, connecte une application à une file RabbitMQ, ajoute un déclencheur Prometheus, configure le scale-to-zero, puis referme le tout dans un projet fonctionnel prêt pour la production. Comptez environ 70 minutes pour suivre les 11 étapes, en plus du temps de téléchargement des images. Ce tutoriel complète notre couverture plus large des sujets cloud et Kubernetes publiée sur shattered.io.
Qu’est-ce que KEDA et pourquoi l’autoscaling événementiel compte en 2026
KEDA (Kubernetes Event-Driven Autoscaling) est un opérateur qui étend le Horizontal Pod Autoscaler natif de Kubernetes. Il observe des sources externes, une file RabbitMQ, un topic Kafka, une requête Prometheus, un calendrier cron, puis traduit cette donnée en métrique exploitable par le HPA. Le projet est passé par l’incubation CNCF avant d’obtenir le statut de projet gradué, un niveau de maturité que la fondation CNCF réserve aux projets jugés stables et largement adoptés en production.
La version 2.21.0 cible les clusters Kubernetes 1.34 à 1.36, en cohérence avec la politique de support N-2 du projet. La branche 2.19, sortie le 2 février 2026, a atteint sa fin de support le 23 septembre 2026, exactement au moment de la sortie de la 2.21. Le calendrier de publication de KEDA suit un rythme fixe (janvier, mai, septembre) documenté dans sa feuille de route, ce qui facilite la planification des mises à jour côté exploitation.
KEDA n’est pas une curiosité de laboratoire. Microsoft livre KEDA comme add-on managé sur Azure Kubernetes Service, avec une version 2.20.2 associée à Kubernetes 1.37 selon le changelog public d’AKS. Scaler un worker qui vide une file de 40 000 messages ou ramener un déploiement à zéro pod pendant la nuit sont deux usages directement liés aux coûts d’infrastructure, un argument qui pèse autant que l’aspect technique dans l’adoption de l’outil.
Avant KEDA, une équipe qui voulait absorber un pic de commandes le soir d’un lancement produit devait soit surprovisionner ses pods toute l’année pour tenir le coup le jour J, soit écrire un script maison qui interroge une file et ajuste les réplicas à la main. Les deux approches coûtent cher, la première en ressources inutilisées, la seconde en maintenance et en fiabilité. KEDA remplace ce script maison par une ressource déclarative versionnée comme le reste du cluster, relue en revue de code au même titre qu’un Deployment ou un Service.
La gouvernance neutre de la CNCF joue aussi un rôle dans l’adoption du projet par de grandes organisations. Un opérateur qui touche directement au nombre de réplicas d’une application critique attire forcément un examen de sécurité plus poussé qu’un simple outil de reporting, et le passage par les étapes sandbox puis incubating puis gradué impose un niveau d’audit et de gouvernance multi-vendeur que peu de projets d’autoscaling concurrents peuvent revendiquer.
Pour une équipe française ou européenne qui opère déjà sur AWS, Azure ou Google Cloud, l’intérêt de KEDA tient aussi à sa portabilité. Les manifestes ScaledObject et ScaledJob s’écrivent de la même façon quel que soit le fournisseur cloud, seul le bloc triggers change de type. Un projet qui migre d’un cloud à l’autre, ou qui tourne en multi-cloud par contrainte réglementaire, conserve donc l’essentiel de sa logique d’autoscaling sans réécriture complète.
KEDA face au Horizontal Pod Autoscaler natif
Le Horizontal Pod Autoscaler standard ajuste le nombre de réplicas en fonction du CPU ou de la mémoire consommée par les pods. Ce modèle fonctionne bien pour des services web classiques, mais il reste aveugle à la profondeur d’une file de messages ou au retard de consommation d’un topic Kafka. KEDA ne remplace pas le HPA, il lui fournit de nouvelles sources de métriques et ajoute des capacités que le HPA seul ne gère pas, notamment la mise à zéro des réplicas.
| Capacité | HPA natif seul | KEDA |
|---|---|---|
| Scaling sur CPU/mémoire | Oui | Oui, via le HPA sous-jacent |
| Scaling sur profondeur de file | Non | Oui (RabbitMQ, SQS, Service Bus) |
| Scaling sur retard Kafka | Non | Oui |
| Scaling sur requête Prometheus | Nécessite un adaptateur tiers | Scaler intégré |
| Scale-to-zero | Non | Oui |
| Scaling planifié (cron) | Non | Oui |
| Scaling de Jobs (ScaledJob) | Non | Oui |
| Authentification dédiée aux triggers | Non | Oui (TriggerAuthentication) |
Cette différence explique pourquoi la plupart des équipes installent KEDA en complément du HPA plutôt qu’à sa place. Chaque ScaledObject KEDA génère en coulisses un HPA standard, visible avec kubectl get hpa, ce qui simplifie le diagnostic puisque les habitudes Kubernetes classiques restent valables.
Techniquement, KEDA s’intègre à Kubernetes via l’API externe de métriques (external.metrics.k8s.io), le même mécanisme d’extension que les fournisseurs cloud utilisent depuis des années pour brancher leurs propres métriques sur le HPA. Le serveur de métriques déployé par le chart Helm agit comme passerelle, il interroge la source externe à intervalle régulier, convertit la valeur lue en métrique Kubernetes standard, puis laisse le contrôleur HPA natif prendre la décision finale de scaling selon sa propre boucle de réconciliation. Aucune logique de scaling ne tourne en dehors de ce mécanisme déjà présent dans le cluster, ce qui limite la surface de nouveauté à apprendre pour une équipe qui connaît déjà Kubernetes.
Prérequis techniques et versions à réunir
Avant de commencer, réunissez un cluster Kubernetes récent et les outils en ligne de commande correspondants. Le tableau suivant liste les versions utilisées dans ce tutoriel, cohérentes avec les exigences officielles de KEDA 2.21.0.
| Composant | Version minimale | Rôle dans ce tutoriel |
|---|---|---|
| Kubernetes | 1.34 (jusqu’à 1.36 supporté) | Cluster cible, local ou managé |
| kubectl | 1.34 | Pilotage du cluster |
| Helm | 3.14 | Installation de l’opérateur KEDA |
| KEDA | 2.21.0 | Opérateur d’autoscaling événementiel |
| RabbitMQ | 3.13 (chart Bitnami ou officiel) | Source d’événements de démonstration |
| Prometheus | 2.5x via kube-prometheus-stack | Scaler basé sur une requête PromQL |
Comptez au moins 2 vCPU et 4 Go de mémoire disponibles sur le cluster pour héberger l’opérateur KEDA, RabbitMQ et l’application de démonstration sans saturer les nœuds. Un cluster local (Kind, Minikube, K3s) convient parfaitement pour suivre ce guide, l’essentiel des manifestes restant identique sur un cluster managé type AKS, GKE ou EKS.
Sur un cluster managé, le metrics-server est déjà présent par défaut, inutile de l’installer séparément. Sur un cluster local monté à la main, vérifiez sa présence avec kubectl top nodes, une erreur à ce stade indique que le metrics-server manque et qu’il faut l’ajouter avant même de penser à KEDA, puisque le HPA sous-jacent en a besoin pour les métriques CPU et mémoire classiques. Côté RabbitMQ, la version 3.13 reste la référence stable au moment de la rédaction, et le chart officiel accepte un mode single node largement suffisant pour suivre ce tutoriel sans monter un cluster RabbitMQ complet.
Étape 1 : vérifier la compatibilité de votre cluster Kubernetes
Commencez par confirmer la version du cluster et la disponibilité des nœuds. KEDA 2.21.0 refuse de s’installer correctement sur une version de Kubernetes antérieure à la fenêtre de support N-2, autant le vérifier avant de perdre du temps sur une installation incomplète.
kubectl version --short
kubectl get nodes -o wide
kubectl create namespace keda
Si la commande kubectl version renvoie une version serveur inférieure à 1.34, mettez à niveau le cluster avant de poursuivre, ou basculez sur un cluster de test jetable. Le namespace keda isole l’opérateur et ses CRD du reste des charges de travail, une pratique recommandée par la documentation officielle.
Profitez aussi de cette étape pour noter le nombre de nœuds et leur capacité disponible avec kubectl describe nodes. Un cluster de développement sous-dimensionné laisse les pods KEDA en attente de planification (Pending), ce qui ressemble à tort à un problème de configuration alors qu’il s’agit simplement d’un manque de ressources sur les nœuds existants.
Étape 2 : installer l’opérateur KEDA 2.21 avec Helm
KEDA se distribue via un chart Helm maintenu par le projet lui-même. L’installation déploie trois composants, l’opérateur qui surveille les ressources personnalisées, le serveur de métriques qui expose les valeurs externes au HPA, et les webhooks d’admission qui valident les manifestes avant leur création.
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda \
--namespace keda \
--version 2.21.0
Vérifiez ensuite que les trois pods démarrent correctement.
kubectl get pods -n keda
NAME READY STATUS RESTARTS AGE
keda-operator-7d4f9b7c8d-x2kqp 1/1 Running 0 45s
keda-operator-metrics-apiserver-5c8f6d9b4c-ht7wn 1/1 Running 0 45s
keda-admission-webhooks-6b9c7d8f5-qp3mn 1/1 Running 0 45s
Un pod bloqué en ImagePullBackOff signale le plus souvent un registre d’images injoignable depuis le cluster. Plusieurs projets CNCF ont récemment déplacé leurs images hors des registres Google, pensez à vérifier que votre cluster résout bien ghcr.io si vous êtes derrière un proxy d’entreprise strict.
L’installation Helm accepte aussi un fichier values.yaml personnalisé pour ajuster les limites de ressources de l’opérateur, activer les webhooks d’admission de manière stricte, ou restreindre la surveillance à une liste de namespaces précise plutôt qu’à l’ensemble du cluster. Pour un premier essai, les valeurs par défaut du chart suffisent largement, l’ajustement fin n’a d’intérêt qu’une fois le comportement de base validé.
Étape 3 : comprendre les CRD ScaledObject, ScaledJob et TriggerAuthentication
KEDA ajoute trois ressources personnalisées au cluster. Le ScaledObject relie un Deployment ou un StatefulSet existant à un ou plusieurs déclencheurs, et c’est lui qui génère le HPA en arrière-plan. Le ScaledJob cible les Jobs Kubernetes plutôt que les Deployments, utile pour un traitement par lot qui doit créer une instance de Job par message plutôt que d’augmenter les réplicas d’un pod continu.
Le TriggerAuthentication sépare les secrets d’accès (clé API, jeton, identifiant de compte de service cloud) de la définition du scaling elle-même. Cette séparation permet de faire relire un ScaledObject par un développeur sans exposer les identifiants de connexion à la file RabbitMQ ou au compte AWS, un détail qui compte dès qu’un dépôt Git versionne ces manifestes.
Il existe une variante nommée ClusterTriggerAuthentication, identique au TriggerAuthentication mais disponible pour tous les namespaces du cluster plutôt qu’un seul. Elle convient à une authentification partagée, par exemple un rôle IAM cloud utilisé par plusieurs équipes, alors que le TriggerAuthentication classique reste préférable quand chaque namespace doit garder ses propres identifiants isolés des autres.
Étape 4 : déployer une application de démonstration
Déployez un worker simple qui consomme des messages. Ce déploiement démarre avec une seule réplique, KEDA se chargera ensuite de la faire varier.
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-worker
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: order-worker
template:
metadata:
labels:
app: order-worker
spec:
containers:
- name: order-worker
image: ghcr.io/exemple/order-worker:1.4.0
env:
- name: RABBITMQ_HOST
value: rabbitmq.default.svc.cluster.local
- name: QUEUE_NAME
value: orders
Appliquez ce manifeste avec kubectl apply -f order-worker.yaml. À ce stade, le déploiement tourne avec une seule réplique fixe, exactement comme avant l’arrivée de KEDA dans le cluster.
Remplacez bien sûr l’image ghcr.io/exemple/order-worker:1.4.0 par votre propre application, le seul prérequis étant qu’elle sache consommer des messages depuis la file ciblée et qu’elle supporte d’être démarrée et arrêtée à tout moment sans perte de message en cours de traitement. Une application qui ne gère pas correctement l’arrêt propre (graceful shutdown) risque de perdre des messages en plein traitement au moment où KEDA retire une réplique devenue inutile.
Étape 5 : créer un ScaledObject branché sur une file RabbitMQ
Le ScaledObject ci-dessous surveille la file orders et ajoute une réplique toutes les 20 messages en attente, jusqu’à un maximum de 15 pods.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: order-worker-scaler
namespace: default
spec:
scaleTargetRef:
name: order-worker
minReplicaCount: 1
maxReplicaCount: 15
pollingInterval: 15
cooldownPeriod: 120
triggers:
- type: rabbitmq
metadata:
queueName: orders
mode: QueueLength
value: "20"
authenticationRef:
name: rabbitmq-trigger-auth
Après application, KEDA crée automatiquement un HPA correspondant. Vérifiez-le avec les deux commandes suivantes.
kubectl get scaledobject order-worker-scaler
NAME SCALETARGETKIND SCALETARGETNAME MIN MAX READY ACTIVE
order-worker-scaler apps/v1.Deployment order-worker 1 15 True True
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
keda-hpa-order-worker-scaler Deployment/order-worker 4/20 (avg) 1 15 1
La colonne ACTIVE passe à True dès que le déclencheur dépasse le seuil configuré. C’est ce signal, et non une variation de CPU, qui pilote désormais la décision de scaling.
Le champ pollingInterval fixé à 15 secondes détermine la fréquence à laquelle KEDA interroge RabbitMQ, un compromis raisonnable entre réactivité et charge ajoutée sur le broker. Le champ cooldownPeriod de 120 secondes retarde la réduction du nombre de réplicas après que la file soit redevenue vide, ce qui évite d’arrêter puis de redémarrer un pod seulement quelques secondes plus tard si un nouveau lot de messages arrive juste après le précédent.
Étape 6 : sécuriser les secrets avec TriggerAuthentication
Créez d’abord un Secret Kubernetes classique contenant les identifiants RabbitMQ, puis référencez-le depuis un TriggerAuthentication plutôt que de l’écrire en clair dans le ScaledObject.
apiVersion: v1
kind: Secret
metadata:
name: rabbitmq-credentials
type: Opaque
stringData:
host: "amqp://scaler-user:[email protected]:5672/"
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-trigger-auth
spec:
secretTargetRef:
- parameter: host
name: rabbitmq-credentials
key: host
Ce découpage évite qu’un identifiant de connexion ne se retrouve dans l’historique Git d’un dépôt d’infrastructure. Pour un déploiement sur AWS ou Azure, TriggerAuthentication accepte aussi une identité de pod managée, ce qui supprime complètement le besoin d’un secret statique.
Dans un pipeline GitOps piloté par ArgoCD ou Flux, seul le Secret doit rester hors du dépôt Git, généralement injecté via un gestionnaire externe comme Vault ou Sealed Secrets. Le TriggerAuthentication et le ScaledObject, eux, se versionnent normalement puisqu’ils ne contiennent aucune valeur sensible, seulement des références à des ressources existantes.
Étape 7 : scaler à partir d’une requête Prometheus
Le scaler Prometheus permet de piloter le nombre de réplicas à partir de n’importe quelle métrique déjà collectée, par exemple la latence moyenne d’une API ou le nombre de connexions actives sur une base de données.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: api-latency-scaler
spec:
scaleTargetRef:
name: api-gateway
minReplicaCount: 2
maxReplicaCount: 20
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus-operated.monitoring.svc:9090
query: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[2m])) by (le))
threshold: "0.8"
Ici, dès que le 95e percentile de latence dépasse 800 millisecondes, KEDA augmente progressivement le nombre de pods de api-gateway. Ce scaler transforme n’importe quelle règle d’alerte Prometheus déjà en place en règle d’autoscaling, sans réécrire la logique de supervision existante.
Ce scaler suppose que le serveur Prometheus indiqué dans serverAddress est joignable depuis le namespace de l’opérateur KEDA, un détail qui piège régulièrement les équipes qui isolent leur stack de supervision dans un namespace dédié avec une politique réseau stricte. Testez la requête PromQL directement dans l’interface Prometheus avant de la copier dans le ScaledObject, une requête mal formée échoue silencieusement côté KEDA plutôt que de remonter une erreur explicite dans les logs applicatifs.
Étape 8 : scale-to-zero, ScaledJob et scaling planifié avec Cron
Fixer minReplicaCount à zéro autorise KEDA à arrêter complètement un déploiement en l’absence d’événement, puis à le redémarrer dès qu’un message réapparaît dans la file. C’est la capacité que le HPA natif ne propose pas, et elle a un impact direct sur la facture d’un cluster payé à l’usage.
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: invoice-batch-job
spec:
jobTargetRef:
template:
spec:
containers:
- name: invoice-worker
image: ghcr.io/exemple/invoice-worker:2.1.0
restartPolicy: Never
minReplicaCount: 0
maxReplicaCount: 30
pollingInterval: 10
triggers:
- type: rabbitmq
metadata:
queueName: invoices
mode: QueueLength
value: "1"
Pour un scaling purement temporel, par exemple remonter la capacité avant l’ouverture des marchés ou avant un pic de trafic connu, le trigger cron suffit et ne nécessite aucune file externe.
triggers:
- type: cron
metadata:
timezone: Europe/Paris
start: 0 7 * * 1-5
end: 0 20 * * 1-5
desiredReplicas: "8"
En dehors de la plage 7h-20h du lundi au vendredi, le déploiement retombe à sa valeur minimale définie ailleurs dans le ScaledObject.
Le ScaledJob mérite une attention particulière sur le champ restartPolicy: Never, obligatoire puisque chaque exécution correspond à un traitement unique plutôt qu’à un processus qui tourne en continu. Contrairement au ScaledObject, un ScaledJob ne génère aucun HPA, KEDA crée directement des objets Job Kubernetes à la demande, visibles avec kubectl get jobs, chacun disparaissant une fois son traitement terminé selon la politique de nettoyage configurée côté Kubernetes.
Étape 9 : connecter KEDA à AWS SQS et Azure Service Bus
Le choix du scaler ne change pas la structure du ScaledObject, seul le bloc triggers et le type d’authentification varient. Le tableau suivant résume les cas d’usage les plus fréquents en entreprise.
| Trigger | Cas d’usage typique | Authentification recommandée |
|---|---|---|
| rabbitmq | Files de tâches internes, microservices | Secret + TriggerAuthentication |
| kafka | Flux d’événements à fort débit | SASL/TLS via TriggerAuthentication |
| aws-sqs-queue | Découplage de services sur AWS | IAM Role for Service Account |
| azure-servicebus | Intégration .NET et messagerie d’entreprise | Managed Identity |
| prometheus | Scaling piloté par une métrique applicative | Aucune ou jeton bearer |
| cron | Anticipation de pics connus à l’avance | Aucune |
Sur AWS, le trigger aws-sqs-queue s’appuie le plus souvent sur un rôle IAM associé au compte de service plutôt que sur une clé d’accès statique.
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.eu-west-3.amazonaws.com/123456789012/orders-queue
queueLength: "25"
awsRegion: eu-west-3
identityOwner: operator
La valeur identityOwner: operator indique à KEDA d’utiliser le rôle IAM attaché au pod de l’opérateur plutôt qu’un secret dédié, une pratique alignée avec les recommandations de sécurité cloud natif.
Côté Azure, le trigger azure-servicebus suit la même logique avec une Managed Identity assignée au pod plutôt qu’à l’opérateur dans son ensemble, ce qui permet de donner à chaque ScaledObject un périmètre d’accès minimal sur un seul topic ou une seule file, plutôt qu’un accès large à l’ensemble du namespace Service Bus. Cette granularité évite qu’une mauvaise configuration sur une application ne donne accidentellement accès aux files d’une autre équipe.
Étape 10 : surveiller KEDA avec Prometheus et Grafana
L’opérateur KEDA expose nativement un point de terminaison de métriques au format Prometheus. Un ServiceMonitor permet de l’intégrer directement à une stack kube-prometheus déjà installée dans le cluster.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: keda-operator-metrics
namespace: keda
spec:
selector:
matchLabels:
app: keda-operator-metrics-apiserver
endpoints:
- port: metrics-server
interval: 30s
Les métriques les plus utiles au quotidien sont le nombre d’erreurs de scaling par ScaledObject et la latence d’évaluation de chaque trigger. Une erreur qui grimpe en continu signale presque toujours un problème d’authentification ou un endpoint externe devenu injoignable, bien avant que l’application ne montre un symptôme visible côté utilisateur.
Un tableau de bord Grafana minimal pour KEDA affiche généralement trois graphiques, le nombre de réplicas courant par ScaledObject comparé à sa valeur cible, le taux d’erreur par type de scaler, et la latence de la boucle de réconciliation de l’opérateur. Ces trois courbes suffisent à repérer en quelques secondes si un pic de trafic a été correctement absorbé ou si un scaler particulier accumule des erreurs sans impacter encore la disponibilité du service.
Étape 11 : finaliser le projet complet, une chaîne de commandes élastique
Assemblez maintenant les pièces précédentes en un seul projet fonctionnel, une chaîne de traitement de commandes qui part de zéro pod au repos, monte jusqu’à 15 pods sous charge, puis redescend automatiquement. Le dossier du projet contient quatre fichiers : deployment.yaml (étape 4), secret-and-auth.yaml (étape 6), scaledobject.yaml (étape 5, avec minReplicaCount: 0 pour autoriser le scale-to-zero complet) et servicemonitor.yaml (étape 10).
order-autoscaling-demo/
├── deployment.yaml
├── secret-and-auth.yaml
├── scaledobject.yaml
└── servicemonitor.yaml
Cette arborescence volontairement courte reste lisible par n’importe quel membre de l’équipe qui n’a jamais touché à KEDA, un critère aussi important que la robustesse technique quand le projet doit survivre au départ de la personne qui l’a mis en place.
kubectl apply -f secret-and-auth.yaml
kubectl apply -f deployment.yaml
kubectl apply -f scaledobject.yaml
kubectl apply -f servicemonitor.yaml
# Injecter 300 messages de test dans la file
kubectl run rabbitmq-publisher --rm -it --restart=Never \
--image=ghcr.io/exemple/queue-loadgen:1.0 -- \
--queue orders --count 300
En observant kubectl get pods -w pendant les minutes suivantes, le nombre de pods order-worker doit grimper par paliers, se stabiliser pendant le traitement des 300 messages, puis redescendre à zéro deux minutes après le dernier message consommé, conformément au cooldownPeriod de 120 secondes défini à l’étape 5. Ce cycle complet, de zéro à plusieurs pods puis retour à zéro, constitue la preuve concrète que l’autoscaling événementiel fonctionne de bout en bout.
Pour aller plus loin, ajoutez le trigger Prometheus de l’étape 7 sur un second ScaledObject qui cible un service api-gateway placé devant la file, et le trigger cron de l’étape 8 sur le même ScaledObject que order-worker pour garantir une capacité plancher pendant les heures ouvrées même sans message en attente. Les trois triggers d’un même ScaledObject se combinent avec une logique OR par défaut, c’est-à-dire que KEDA scale vers le haut dès que l’un des triggers dépasse son seuil, ce qui convient à la plupart des scénarios de production où plusieurs signaux indépendants justifient chacun une augmentation de capacité.
Ce projet complet reproduit à petite échelle ce que des équipes de plus grande taille appliquent à des chaînes de traitement bien plus larges, la différence tenant surtout au nombre de files et de services connectés, pas à la logique de scaling elle-même qui reste identique qu’il s’agisse de trois pods ou de trois cents.
Erreurs fréquentes et dépannage KEDA
Cinq erreurs fréquentes à éviter
- Oublier le minReplicaCount à 0 puis s’étonner de l’absence de scale-to-zero : par défaut KEDA conserve une réplique minimale, le scale-to-zero doit être explicitement demandé.
- Mettre les identifiants directement dans le ScaledObject : sans TriggerAuthentication, le secret se retrouve en clair dans l’historique Git et dans la sortie de
kubectl get scaledobject -o yaml. - Choisir un pollingInterval trop agressif : interroger une file toutes les 2 secondes sur des centaines de ScaledObject surcharge le service externe interrogé, 15 à 30 secondes suffisent dans l’immense majorité des cas.
- Ignorer le cooldownPeriod : une valeur trop basse provoque un effet de yo-yo, le déploiement scale puis descale en boucle sur une charge qui fluctue légèrement.
- Mélanger plusieurs ScaledObject sur le même Deployment : KEDA attend une relation un pour un entre un ScaledObject et sa cible, un second ScaledObject sur la même ressource entre en conflit avec le premier.
Huit problèmes de dépannage courants
- Le ScaledObject reste à READY=False : vérifiez les événements avec
kubectl describe scaledobject, la cause la plus fréquente est un Deployment introuvable car mal nommé dansscaleTargetRef. - ACTIVE=False en permanence malgré une file pleine : contrôlez que le TriggerAuthentication référencé existe réellement et pointe vers le bon Secret.
- Le HPA généré n’apparaît pas : exécutez
kubectl get events -n default --field-selector involvedObject.kind=ScaledObjectpour voir l’erreur exacte renvoyée par le serveur de métriques KEDA. - Pods bloqués en ImagePullBackOff après l’installation Helm : vérifiez la résolution DNS du registre d’images et les éventuelles restrictions de pare-feu sortant du cluster.
- Scaling trop lent pour réagir à un pic brutal : réduisez le
pollingIntervaluniquement pour ce trigger précis plutôt que globalement sur tout le cluster. - Erreur d’authentification sur un scaler cloud (SQS, Service Bus) : confirmez que le rôle IAM ou la Managed Identity dispose bien des permissions de lecture sur la file ciblée, pas seulement d’écriture.
- Webhook d’admission qui rejette un ScaledObject valide : un webhook périmé après une mise à niveau partielle de KEDA en est souvent la cause, redéployez l’intégralité du chart Helm plutôt qu’un composant isolé.
- Le ScaledJob crée trop de Jobs simultanément : plafonnez avec
maxReplicaCountet réglezparallelismdans le template du Job pour contrôler la charge sur les ressources en aval.
Sécurité, CVE 2026 et bonnes pratiques pour la production
Un audit de sécurité public portant sur KEDA, publié par l’Open Source Technology Improvement Fund en 2026, détaille un comportement résiduel lié à CVE-2025-68476 permettant de cibler directement le jeton du compte de service de l’opérateur, ainsi qu’une gestion insuffisante des redirections HTTP dans le scaler Pulsar. Le projet a introduit la variable d’environnement KEDA_HTTP_MIN_TLS_VERSION pour forcer une version minimale de TLS sur les connexions sortantes des scalers HTTP, une mitigation à activer explicitement dans les environnements exposés.
Côté bonnes pratiques, limitez les droits RBAC du compte de service de l’opérateur KEDA au strict périmètre des namespaces où l’autoscaling est réellement utilisé, plutôt qu’un accès cluster-wide par défaut. Appliquez une politique réseau qui n’autorise l’opérateur à joindre que les endpoints de scalers effectivement configurés, et surveillez les notes de version publiées sur le dépôt GitHub de KEDA pour anticiper la fin de support d’une branche avant qu’elle ne devienne une faille non corrigée. Le tableau de compatibilité maintenu par endoflife.date reste la référence la plus rapide pour vérifier qu’une version de production se trouve toujours dans la fenêtre de support.
Gardez aussi un œil sur la fréquence de rotation des identifiants utilisés par vos TriggerAuthentication. Un jeton RabbitMQ ou une clé d’accès cloud qui ne tourne jamais représente une dette de sécurité qui s’accumule silencieusement, d’autant plus critique que ce jeton donne indirectement à KEDA le pouvoir de faire varier la capacité d’une application en production.
Pour les équipes qui déploient sur AKS, la documentation officielle de l’add-on KEDA managé décrit les écarts de configuration entre l’installation Helm classique et la version packagée par Microsoft, notamment sur la gestion automatique des mises à jour mineures.
Autre réflexe utile en production, limitez le champ maxReplicaCount de chaque ScaledObject à une valeur cohérente avec le budget de calcul réellement disponible sur le cluster. Un plafond trop élevé combiné à une file qui explose en cas d’incident en aval peut déclencher une tentative de scaling massive qui épuise les ressources du cluster avant même que l’incident d’origine ne soit traité, un effet domino que seule une limite réaliste permet d’éviter.
Conseils avancés pour aller au-delà du tutoriel
Une fois les bases maîtrisées, plusieurs réglages fins font la différence entre une installation KEDA qui fonctionne et une installation qui tient la charge en production sans surveillance constante. Le champ advanced.horizontalPodAutoscalerConfig d’un ScaledObject permet de régler les politiques de comportement du HPA généré, par exemple limiter la vitesse de réduction des réplicas (scaleDown.policies) indépendamment du cooldownPeriod global, un niveau de contrôle utile quand plusieurs triggers aux dynamiques différentes cohabitent sur le même ScaledObject.
Pour les files à très fort débit, évitez de faire porter tout le calcul de seuil sur KEDA seul. Combinez un trigger Kafka avec une métrique applicative exposée par la consommatrice elle-même (temps de traitement moyen par message, par exemple), ce qui donne à l’opérateur deux signaux complémentaires plutôt qu’un seul indicateur de profondeur de file qui peut rester trompeur si la taille moyenne des messages varie fortement dans le temps.
Enfin, testez le comportement de vos ScaledObject sous charge artificielle avant la mise en production, avec un outil de génération de charge qui pousse délibérément la file au-delà du seuil configuré. Cette répétition révèle souvent des limites invisibles en conditions normales, par exemple un registre d’images trop lent à servir de nouvelles images de conteneur quand quinze pods démarrent en même temps, un problème d’infrastructure sans rapport direct avec KEDA mais qui ne se révèle qu’au moment d’un scaling massif.
Foire aux questions
KEDA remplace-t-il le Horizontal Pod Autoscaler ?
Non. KEDA s’installe en complément du HPA natif et génère automatiquement un objet HPA pour chaque ScaledObject créé. Désinstaller KEDA fait disparaître ces HPA générés, mais le mécanisme de scaling natif de Kubernetes reste intact pour le reste du cluster, et les Deployments qui n’utilisaient pas KEDA continuent de fonctionner exactement comme avant, sans aucun effet de bord.
Quelle version de Kubernetes faut-il pour KEDA 2.21 ?
KEDA 2.21.0 est documenté pour les versions Kubernetes 1.34 à 1.36, conformément à la politique de support N-2 du projet. Une version plus ancienne du cluster nécessite d’installer une branche KEDA antérieure, avec un support limité dans le temps. Le site endoflife.date publie un tableau à jour de ces correspondances de versions, pratique pour planifier une montée de version conjointe du cluster et de l’opérateur.
Le scale-to-zero est-il risqué en production ?
Il convient de le réserver aux charges tolérantes à une latence de démarrage, le temps que le premier pod redémarre après un message. Pour une API utilisateur critique, une valeur minReplicaCount de 1 ou 2 évite ce délai tout en gardant le bénéfice du scaling vers le haut. Les traitements par lot, les workers asynchrones ou les tâches planifiées de nuit restent les meilleurs candidats au scale-to-zero complet, puisqu’un léger délai de démarrage n’y affecte aucun utilisateur final en attente d’une réponse immédiate.
Combien de scalers KEDA prend-il en charge ?
Le projet documente plus de 50 scalers intégrés couvrant les files de messages, les bases de données, les métriques cloud et les systèmes de supervision. La liste complète et à jour se trouve dans la documentation officielle de KEDA 2.21. Des scalers plus récents comme NSQ et Temporal sont venus s’ajouter à la liste lors de précédentes versions, un signe que le catalogue continue de s’élargir au rythme des demandes de la communauté plutôt que de rester figé.
Peut-on utiliser KEDA avec un ScaledJob et un ScaledObject sur la même application ?
Techniquement oui si l’application distingue un composant Deployment et un composant Job, mais un ScaledObject et un ScaledJob ne peuvent pas cibler la même ressource simultanément. Il est courant, par exemple, de garder un ScaledObject pour la partie API toujours disponible et un ScaledJob séparé pour les traitements par lot déclenchés ponctuellement par la même application.
KEDA fonctionne-t-il sur un cluster local comme Minikube ou K3s ?
Oui, l’installation Helm est identique. Seule la connectivité réseau vers les sources d’événements externes (RabbitMQ, cloud) doit être vérifiée, ce qui est généralement plus simple sur un cluster local que sur un environnement de production cloisonné.
Que se passe-t-il si le service externe surveillé par KEDA devient indisponible ?
Le ScaledObject passe en erreur d’évaluation du trigger, visible dans les événements Kubernetes et dans les métriques exposées par l’opérateur. Selon la configuration, KEDA conserve le dernier nombre de réplicas connu plutôt que de scaler dans le vide, ce qui évite qu’une simple coupure réseau temporaire ne vide brutalement un déploiement critique à zéro pod.
KEDA a-t-il un coût de licence ?
KEDA est un projet open source sous licence Apache 2.0, sans coût de licence propre. Les coûts proviennent uniquement des ressources de calcul consommées par l’opérateur lui-même, qui reste léger, et par les pods mis à l’échelle. Les offres managées comme l’add-on AKS peuvent ajouter leurs propres conditions tarifaires côté infrastructure cloud, mais KEDA en tant que logiciel reste gratuit dans tous les cas, y compris pour un usage commercial.
