Packaging & Config

Karpenter

Autoscaler de nœuds Kubernetes CNCF - provisionne les nœuds EC2 en secondes selon les pods pending, consolidation automatique, NodePool/EC2NodeClass. Apache 2.0, AWS.

Karpenter est un autoscaler de nœuds Kubernetes développé par AWS, CNCF Incubating. Contrairement au Cluster Autoscaler qui opère sur des node groups existants, Karpenter provisionne directement les instances cloud (EC2 pour AWS) adaptées aux pods en attente, en quelques secondes. Il gère la consolidation automatique des nœuds sous-utilisés (bin packing), le déprovisionnement des nœuds vides, et supporte les interruptions Spot. La configuration se fait via les CRDs NodePool (contraintes de scheduling) et EC2NodeClass (configuration AWS).

Karpenter est conçu pour AWS (EKS). Un provider Azure distinct (azure.com/karpenter) existe pour AKS, maintenu par Microsoft.


Informations essentielles

Origine : AWS → CNCF Incubating  ·  Licence : Apache 2.0  ·  Architectures : x86_64, ARM64

Liens : Site officiel  ·  Documentation  ·  GitHub  ·  Releases

Support : CNCF Incubating. Maintenu activement par AWS, utilisé en production chez AWS, Lyft, Sumo Logic.

Stack par défaut

ComposantValeur
CRDsNodePool, EC2NodeClass, NodeClaim
Cloud providerAWS (EKS natif), Azure (provider séparé pour AKS)
ProvisionnementDirect EC2 (sans node group ASG)
ConsolidationAutomatique (bin packing + déprovisionnement)
Instance selectionMulti-type, Spot/On-Demand, graviton
Namespace installkarpenter

Prérequis

RessourceValeur
EKSCluster EKS (pour le provider AWS officiel)
IRSAIAM Role for Service Account configuré pour Karpenter
Sous-réseauSubnets taggés karpenter.sh/discovery: <cluster-name>
Security GroupTaggé karpenter.sh/discovery: <cluster-name>
Instance profileIAM Instance Profile pour les nœuds EC2

Installation sur EKS

export CLUSTER_NAME=my-cluster
export AWS_REGION=eu-west-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export KARPENTER_NAMESPACE=karpenter

helm repo add karpenter https://charts.karpenter.sh/
helm repo update

# Installer Karpenter (le IRSA doit être configuré au préalable)
helm install karpenter oci://public.ecr.aws/karpenter/karpenter \
  --version 1.0.0 \
  --namespace ${KARPENTER_NAMESPACE} --create-namespace \
  --set settings.clusterName=${CLUSTER_NAME} \
  --set settings.interruptionQueue=${CLUSTER_NAME} \
  --set controller.resources.requests.cpu=1 \
  --set controller.resources.requests.memory=1Gi

# Vérifier
kubectl get pods -n karpenter

NodePool - contraintes de scheduling

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      nodeClassRef:
        apiVersion: karpenter.k8s.aws/v1
        kind: EC2NodeClass
        name: default
      requirements:
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"]       # Intel ET Graviton
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]    # Préférer Spot
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["c", "m", "r"]          # Compute, General, Memory
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ["2"]
  limits:
    cpu: 1000                              # Max 1000 vCPU dans ce NodePool
    memory: 4000Gi
  disruption:
    consolidationPolicy: WhenEmpty         # Déprovisionner les nœuds vides
    consolidateAfter: 30s

EC2NodeClass - configuration AWS

apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  amiSelectorTerms:
    - alias: al2023@latest                 # Amazon Linux 2023 (latest)
  role: KarpenterNodeRole-${CLUSTER_NAME}  # IAM Instance Profile
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: ${CLUSTER_NAME}
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: ${CLUSTER_NAME}
  tags:
    managed-by: karpenter
    cluster: ${CLUSTER_NAME}

Annotations sur les pods

spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"   # Ne pas interrompre ce pod
    spec:
      # Forcer un type d'instance spécifique
      nodeSelector:
        karpenter.k8s.aws/instance-family: m5

      # Tolérer les nœuds Spot
      tolerations:
        - key: karpenter.sh/capacity-type
          value: spot
          operator: Equal
          effect: NoSchedule

Mise à jour

helm upgrade karpenter oci://public.ecr.aws/karpenter/karpenter \
  --version <nouvelle-version> \
  --namespace karpenter \
  --reuse-values

Troubleshooting

# État de Karpenter
kubectl get pods -n karpenter

# Logs du contrôleur
kubectl logs -n karpenter \
  -l app.kubernetes.io/name=karpenter --tail=100 -f

# Voir les NodeClaims (demandes de nœuds)
kubectl get nodeclaims

# Voir les Nodes créés par Karpenter
kubectl get nodes -l karpenter.sh/nodepool

# Pods en Pending (déclenchent le provisionnement)
kubectl get pods -A --field-selector status.phase=Pending

# Vérifier les événements de disruption/consolidation
kubectl get events -n karpenter

# Karpenter ne provisionne pas : vérifier
# 1. IRSA - rôle IAM bien attaché au service account
kubectl describe sa karpenter -n karpenter
# 2. Subnets taggés correctement
aws ec2 describe-subnets --filters "Name=tag:karpenter.sh/discovery,Values=${CLUSTER_NAME}"

Ressources

Newsletter · 2 000+ abonnés

Reste au courant de ce qui bouge en prod

RudeOps veille devops hebdo, droit au but.

Gratuit · Sans spam · Désinscription en un clic