Le cluster-autoscaler historique de Kubernetes fonctionne, mais avec un modèle qui montre ses limites : on déclare des Node Groups statiques (Auto Scaling Groups côté AWS, MIG côté GCP), le scaler ajuste leur taille. Pour des charges hétérogènes, ça force à multiplier les Node Groups par instance type, par zone, par architecture, et l'optimisation des coûts reste laborieuse.
Karpenter inverse l'approche : on déclare ce dont les pods ont besoin, et le contrôleur provisionne les instances optimales directement, sans Node Groups. Cet article présente l'architecture, déploie un cluster AWS type, compare à cluster-autoscaler et liste les pièges connus.
Plan de l'article
- Qu'est-ce que Karpenter
- Architecture : NodePool + NodeClass
- Provisioning et consolidation
- Déploiement sur EKS
- Comparaison Karpenter vs cluster-autoscaler
- Disruption et drift
- Cas d'usage et limites
Qu'est-ce que Karpenter
Karpenter est un autoscaler de nœuds Kubernetes développé sous l'égide du SIG kubernetes-sigs, distribué sous licence Apache 2.0. La dernière version stable au moment de la rédaction est la v1.12.0, publiée le 24 avril 2026.
Le projet a été lancé par AWS en 2021, puis donné à la communauté Kubernetes. Il existe aujourd'hui sous deux formes :
- Le projet cœur (
kubernetes-sigs/karpenter) : la logique générique d'autoscaling. - Les providers spécifiques : AWS, Azure, AlibabaCloud, GCP, IBM Cloud, Oracle, Proxmox, Cluster API, Exoscale, Bizfly Cloud, Akamai/Linode (alpha).
Le provider AWS (aws/karpenter-provider-aws) est de loin le plus mature. Le provider Azure suit. Les autres sont à divers degrés d'avancement.
Trois éléments distinguent Karpenter de cluster-autoscaler :
- Pas de Node Groups. Karpenter provisionne directement des instances individuelles selon les besoins des pods en attente.
- Décision basée sur les contraintes des pods. Architecture, OS, instance types, zones, capacité, prix : tout est exprimé dans les contraintes des pods et des NodePools.
- Consolidation continue. Karpenter détecte les nœuds sous-utilisés et les remplace en permanence par des configurations plus denses ou moins coûteuses.
Architecture : NodePool + NodeClass
L'API Karpenter se compose de deux ressources principales.
NodePool : ressource Karpenter générique. Décrit les contraintes générales (architectures, OS, capacity types, zones, taints) et les politiques de disruption.
NodeClass : ressource spécifique au cloud provider. Pour AWS : EC2NodeClass. Décrit les détails AMI, security groups, subnets, instance metadata, IAM role.
Exemple minimal sur EKS :
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ['spot', 'on-demand']
- key: kubernetes.io/arch
operator: In
values: ['amd64', 'arm64']
- key: karpenter.k8s.aws/instance-category
operator: In
values: ['c', 'm', 'r']
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ['5']
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30s
limits:
cpu: '1000'
memory: 1000Gi
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2023
role: KarpenterNodeRole-prod
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: prod
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: prod
Ces deux ressources suffisent à autoscaler le cluster : Karpenter observera les pods unschedulable, déterminera les instances candidates, choisira la moins chère qui respecte les contraintes, et la provisionnera.
Provisioning et consolidation
Le cycle Karpenter standard :
- Un Deployment scale up. Des pods passent en
Pendingcar aucun nœud disponible ne convient. - Karpenter observe ces pods et leurs
nodeSelector,tolerations,topologySpreadConstraints,requests. - Karpenter calcule la combinaison d'instances la plus économique qui satisfait toutes les contraintes (un seul gros nœud ou plusieurs petits, on-demand ou spot, AMD64 ou ARM64).
- L'instance est provisionnée et bootstrappée. Sur EKS, le temps total typique est de 30 à 60 secondes.
- Les pods sont schedulés.
La consolidation s'exécute en continu :
- Si un nœud devient vide après le départ de pods, il est terminé.
- Si plusieurs nœuds peu chargés peuvent être remplacés par un nœud plus gros et moins cher, Karpenter exécute le remplacement.
- Si un type d'instance moins coûteux qui satisfait les contraintes devient disponible, Karpenter peut basculer.
C'est la différence majeure avec cluster-autoscaler, qui ne consolidait qu'à la marge en supprimant des nœuds totalement vides.
Déploiement sur EKS
Le déploiement de référence sur AWS EKS suit cette séquence (helm chart officiel) :
# Récupérer un cluster EKS existant
export CLUSTER_NAME=prod
export AWS_REGION=eu-west-3
# Installer Karpenter via Helm
helm registry login --username AWS --password $(aws ecr-public get-login-password --region us-east-1) public.ecr.aws
helm install karpenter \
oci://public.ecr.aws/karpenter/karpenter \
--version 1.12.0 \
--namespace karpenter --create-namespace \
--set settings.clusterName=$CLUSTER_NAME \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::$ACCOUNT_ID:role/KarpenterController-prod \
--wait
# Appliquer NodePool + EC2NodeClass
kubectl apply -f nodepool.yaml
kubectl apply -f ec2nodeclass.yaml
# Vérifier
kubectl get nodepool
kubectl get ec2nodeclass
Côté IAM, deux rôles sont nécessaires : un pour le contrôleur (KarpenterController) et un pour les nœuds provisionnés (KarpenterNodeRole). Les templates IaC officiels (CloudFormation, Terraform) sont disponibles dans la documentation getting-started.
Comparaison Karpenter vs cluster-autoscaler
| Critère | Karpenter | cluster-autoscaler |
| Modèle | Pas de Node Groups, instances directes | Node Groups (ASG/MIG) statiques |
| Latence de provisioning | 30-60 s typique sur EKS | 1-3 minutes typique (ASG warming) |
| Optimisation des instances | Choisit l'instance la moins chère qui respecte les contraintes | Limite par instance type du Node Group |
| Consolidation | Continue, agressive | Suppression de nœuds vides uniquement |
| Spot + on-demand mix | Géré au niveau du NodePool | Plusieurs Node Groups séparés |
| Architecture multi-arch | Natif | Plusieurs Node Groups |
| Observabilité | Métriques Prometheus riches | Métriques basiques |
| Cloud providers | AWS mature, Azure, GCP, autres divers | Très large (tous les clouds) |
| Installation | Plus simple (helm + 2 CRD) | ASG/MIG à pré-créer |
Pour un cluster AWS EKS ou Azure AKS moderne, Karpenter offre des gains très concrets sur les coûts (consolidation continue, spot mix sans Node Group dédié) et sur la rapidité du scale up. Sur les autres providers ou pour des cas d'usage très spécifiques (autoscaling de pools GPU précis, intégrations avec des systèmes legacy), cluster-autoscaler reste pertinent.
Disruption et drift
Karpenter introduit la notion de disruption : la décision de terminer un nœud, qui peut survenir pour plusieurs raisons.
- Empty consolidation : nœud vide.
- Multi-node consolidation : plusieurs nœuds remplaçables par un plus efficace.
- Drift : un nœud ne correspond plus à la configuration courante du NodePool/NodeClass (par exemple, l'AMI a été mise à jour). Karpenter le marque "drifted" et le remplace selon la politique configurée.
- Expiration : durée de vie maximale d'un nœud (configurable, par défaut désactivée). Utile pour forcer le rolling périodique.
Pour protéger des workloads critiques, on pose un PodDisruptionBudget ou on annote le pod avec karpenter.sh/do-not-disrupt: "true". Pour les workloads stateful, c'est essentiel pour éviter qu'un nœud soit terminé pendant qu'une opération critique tourne.
Cas d'usage et limites
Cas d'usage où Karpenter brille
- Clusters EKS multi-tenants avec workloads très variables : Karpenter optimise au pod près.
- Workloads spot-friendly : mix spot/on-demand par NodePool, avec fallback automatique en cas de perte d'instances spot.
- Plateformes CI/CD : burst soudain de pods de build, scale up rapide, consolidation immédiate après les builds.
- AI/ML training : NodePools dédiés GPU avec contraintes précises, scale up à la demande.
Limites à connaître
Provider AWS très en avance. Si vous n'êtes pas sur AWS, vérifiez la maturité du provider de votre cloud avant de vous engager. Azure progresse vite, GCP et les autres sont moins matures.
Pas de quota par NodePool natif sur tous les axes. Les limits couvrent CPU et mémoire, mais pas le coût direct. Pour borner un budget, il faut combiner avec des quotas du cloud provider ou des outils comme Kubecost.
Disruption potentiellement agressive. Sans PodDisruptionBudget, Karpenter peut consolider même les workloads importants. Discipline nécessaire dans la déclaration des PDB.
Pas adapté aux clusters bare-metal. Karpenter suppose un cloud provider qui peut provisionner des instances à la demande. Pour des clusters on-premise sans API d'instance, cluster-autoscaler ou un autoscaler dédié sont plus adaptés.
Perspectives complémentaires
- Kubernetes haute disponibilité
- GitLab CI sur Kubernetes
- Kubecost : monitoring des coûts Kubernetes
- FinOps en production
- Capacity planning
Sources
- Karpenter (dépôt kubernetes-sigs) code, releases, version v1.12.0
- Documentation officielle, concepts, getting started, NodePool, NodeClass
- Provider AWS, implémentation EKS
- Disruption documentation, politiques de remplacement de nœuds
Conclusion
Karpenter ne remplace pas cluster-autoscaler dans tous les contextes, mais sur AWS EKS et de plus en plus sur Azure AKS, il offre un modèle d'autoscaling nettement plus moderne : provisioning rapide, optimisation continue des coûts, gestion native du mix spot/on-demand et multi-arch sans multiplier les Node Groups. Pour des charges hétérogènes ou variables, le ROI est tangible.


