Introduction
La planification de la capacité des nœuds Kubernetes consiste à déterminer la taille et le nombre appropriés de nœuds pour exécuter vos charges de travail de manière fiable et rentable. Sans planification, vous risquez soit le surprovisionnement (gaspillage d’argent), soit le sous-provisionnement (provoquant des évictions de pods, des échecs de planification et des interruptions de service). Ce guide fournit une approche pratique, étape par étape, pour planifier, dimensionner et gérer la capacité des nœuds Kubernetes, avec des commandes concrètes, des exemples et des stratégies de récupération.
Cet article s’adresse aux développeurs, consultants DevOps et équipes techniques de startups qui exploitent des clusters Kubernetes. Nous couvrons les concepts clés de la mise à l’échelle des nœuds, des demandes et limites de ressources, du dimensionnement des nœuds et de l’autoscaling. Chaque recommandation est versionnée, observable et réversible lorsque cela est possible.
L’objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d’impact, utiliser des espaces réservés au lieu de secrets, vérifier les résultats et documenter les chemins de récupération en cas de problème.
Inventaire des versions et de l’environnement
Avant de prendre toute décision de capacité, vous devez avoir une vision claire de la version de votre cluster, de la composition des pools de nœuds et des outils disponibles. Cet inventaire réduit les risques et garantit que chaque étape ultérieure est compatible avec votre environnement.
Identifier les versions du cluster et des nœuds
Exécutez les commandes en lecture seule suivantes pour recueillir les informations de version :
kubectl version --short
kubectl get nodes -o wide
Exemple de sortie :
Client Version: v1.29.2
Server Version: v1.28.5
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node-pool-a-7f3d Ready <none> 30d v1.28.5 10.0.1.10 <none> Ubuntu 22.04.3 LTS 5.15.0-105-generic containerd://1.7.13
node-pool-b-8a2e Ready <none> 30d v1.28.5 10.0.1.11 <none> Ubuntu 22.04.3 LTS 5.15.0-105-generic containerd://1.7.13
Notez le runtime de conteneur et l’image du système d’exploitation, car ils affectent la surcharge des ressources. Pour les clusters gérés (EKS, GKE, AKS), utilisez la CLI du fournisseur cloud ou la console pour vérifier les configurations des pools de nœuds.
Vérifier la capacité disponible
Utilisez kubectl describe nodes pour voir les ressources allouables et l’utilisation actuelle :
kubectl describe node <node-name> | grep -A 5 "Allocated resources"
Exemple :
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1250m (62%) 3400m (170%)
memory 2.5Gi (50%) 6.8Gi (136%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-1Gi 0 (0%) 0 (0%)
Cela montre que les demandes de CPU sont à 62 % de la capacité allouable, mais que les limites sont à 170 %, ce qui signifie que le nœud est surchargé. La surcharge peut entraîner de la contention et du throttling, mais elle est parfois acceptable pour des charges de travail en rafale.
Prérequis pour la planification de capacité
- Accès à un cluster Kubernetes (version 1.21+ recommandée pour les API d’autoscaling stables).
kubectlconfiguré avec les autorisations RBAC appropriées pour lister les nœuds, les pods et les événements.- Metrics Server installé pour les commandes
kubectl top(sinon, installez-le viakubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml). - Cluster Autoscaler ou autoscaling du fournisseur cloud activé si vous prévoyez de faire évoluer automatiquement les nœuds.
Petit test avant grands changements
Lorsque vous expérimentez avec les paramètres de capacité, appliquez d’abord les modifications à un seul pod ou namespace. Par exemple :
kubectl apply -f test-pod.yaml --dry-run=client
kubectl apply -f test-pod.yaml
kubectl get pod test-pod -o wide
kubectl logs test-pod
Vérifiez que le pod se planifie et fonctionne comme prévu avant de déployer les modifications sur toutes les charges de travail.
Chemin de configuration sûr
Le chemin de configuration sûr consiste à définir correctement les demandes et limites de ressources sur vos pods. C’est la base de la planification de capacité car le planificateur utilise les demandes pour décider où placer les pods, et le kubelet applique les limites pour prévenir la pénurie de ressources.
Comprendre les demandes et limites
- Demandes (Requests) : la quantité de CPU ou de mémoire garantie à un conteneur. Le planificateur additionne les demandes pour déterminer si un nœud a suffisamment de capacité.
- Limites (Limits) : la quantité maximale qu’un conteneur peut utiliser. En cas de dépassement, le CPU est throttlé et la mémoire peut provoquer un OOMKill.
Exemple de spécification de pod
Voici un manifeste de déploiement avec des paramètres de ressources réalistes pour une application web :
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: web
image: nginx:1.25
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
Appliquez et vérifiez :
kubectl apply -f webapp.yaml
kubectl get pods -l app=webapp -o wide
kubectl top pods -l app=webapp
La sortie attendue montre les pods planifiés et l’utilisation du CPU/mémoire dans les limites.
Calculer la capacité des nœuds
Supposons un nœud avec 4 vCPU et 16 GiB de mémoire. La capacité allouable est généralement légèrement inférieure en raison de la surcharge système (par exemple, 3,9 vCPU, 14,9 GiB).
Avec les demandes de pod ci-dessus (250m CPU, 256Mi mémoire), vous pouvez placer environ :
- CPU : 3,9 vCPU / 0,25 vCPU = 15,6, donc 15 pods par nœud.
- Mémoire : 14,9 GiB / 0,256 GiB = 58,2, mais la mémoire est souvent la contrainte la plus stricte pour d’autres charges de travail.
Cependant, vous ne devez jamais remplir un nœud à 100 % de demandes. Réservez de la marge pour les pods système, les daemonsets et la capacité de rafale. Une cible courante est de 70 à 80 % de la capacité allouable pour les demandes.
Définir des quotas de ressources et des plages de limites
Pour empêcher une seule équipe ou un namespace de consommer toute la capacité des nœuds, définissez des ResourceQuotas et des LimitRanges.
Exemple de LimitRange pour appliquer des demandes et limites par défaut :
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-a
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "250m"
memory: "256Mi"
type: Container
Exemple de ResourceQuota :
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
Appliquez et vérifiez :
kubectl apply -f limitrange.yaml
kubectl apply -f resourcequota.yaml
kubectl describe resourcequota -n team-a
Dimensionner correctement les charges de travail
Utilisez kubectl top au fil du temps pour voir l’utilisation réelle et ajuster les demandes en conséquence. Une pratique courante consiste à définir les demandes proches de l’utilisation moyenne et les limites au niveau des pics ou des rafales.
Exemple :
kubectl top pods -n team-a
Si un pod utilise en moyenne 120m de CPU mais demande 500m, vous pouvez réduire la demande pour économiser de la capacité. S’il monte en pic à 900m, définissez la limite à 1000m.
Vérification et diagnostics
Après avoir configuré les ressources, vous devez vérifier que le cluster se comporte comme prévu et diagnostiquer tout problème. Cette section couvre les commandes clés et leur interprétation.
Vérification de la planification
Vérifiez que les pods sont planifiés et en cours d’exécution :
kubectl get pods -o wide
kubectl describe pod <pod-name> | grep -A 10 Events
Si un pod est en attente, les événements peuvent montrer :
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 12s default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
Cela indique qu’aucun nœud n’a suffisamment de CPU pour satisfaire la demande du pod. Vous devrez peut-être ajouter des nœuds ou réduire la demande du pod.
Surveillance de l’utilisation des ressources
Sans Metrics Server, utilisez kubectl top pour voir l’utilisation actuelle :
kubectl top nodes
kubectl top pods -A
Exemple de sortie de nœud :
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node-pool-a-7f3d 920m 23% 7.8Gi 52%
node-pool-b-8a2e 1800m 45% 12.1Gi 81%
Une utilisation élevée de la mémoire sur le nœud-b suggère qu’il est peut-être proche du seuil d’éviction.
Journaux et événements pour le dépannage
Pour les pods qui plantent ou redémarrent :
kubectl logs <pod-name> --previous
kubectl describe pod <pod-name> | grep -A 5 "Last State"
Recherchez OOMKilled dans la raison de terminaison :
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Si un pod est OOMKilled, augmentez sa limite de mémoire ou réduisez son utilisation de la mémoire.
Vérification du Cluster Autoscaler
Si le Cluster Autoscaler (CA) est activé, consultez ses journaux pour voir les décisions de mise à l’échelle :
kubectl logs -n kube-system deployment/cluster-autoscaler
Recherchez des lignes comme :
Fast evaluation: node node-pool-a-7f3d may be scale down candidate
Adding node pool node-pool-a to scale up: 1
Le CA ne monte en charge que lorsqu’un pod est non planifiable en raison de ressources insuffisantes. Il réduit les nœuds sous-utilisés après une période (10 minutes par défaut).
Simuler l’épuisement de la capacité
Pour tester en toute sécurité vos compétences en diagnostic, créez un pod avec une demande importante qui ne peut pas être satisfaite :
apiVersion: v1
kind: Pod
metadata:
name: huge-pod
spec:
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
resources:
requests:
cpu: "100"
memory: "100Gi"
Appliquez et observez :
kubectl apply -f huge-pod.yaml
kubectl get pod huge-pod
kubectl describe pod huge-pod | grep -A 5 Events
Vous devriez voir un événement FailedScheduling. Supprimez le pod ensuite.
Modes de défaillance et récupération
La planification de la capacité doit tenir compte des défaillances. Cette section décrit les modes de défaillance courants, comment les détecter et les actions de récupération.
Pression sur les nœuds et évictions
Lorsque la mémoire ou le disque d’un nœud devient critique, le kubelet évince les pods. Les seuils d’éviction sont configurables mais ont des valeurs par défaut. Surveillez les conditions des nœuds :
kubectl describe node <node-name> | grep -A 5 Conditions
Recherchez :
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure True Thu, 01 Jan 2026 12:00:00 +0000 Thu, 01 Jan 2026 11:55:00 +0000 KubeletHasInsufficientMemory kubelet has insufficient memory available
Récupération : ajoutez des nœuds, réduisez l’utilisation de la mémoire ou ajustez les seuils d’éviction (avec prudence).
Manque d’espace disque
La pression du disque peut empêcher le démarrage de nouveaux pods et provoquer le garbage collection des images. Vérifiez l’utilisation du disque :
kubectl describe node <node-name> | grep -A 5 "DiskPressure"
Récupération : nettoyez les images inutilisées (crictl rmi --prune sur le nœud), ajoutez de l’espace disque ou déplacez le stockage éphémère vers un volume plus grand.
Pod en attente en raison de ressources insuffisantes
Comme vu précédemment, un pod peut rester en attente. Vérifiez d’abord si le cluster autoscaler peut ajouter des nœuds. Sinon, vous devrez peut-être faire évoluer manuellement le pool de nœuds.
Pour les fournisseurs cloud, utilisez la CLI pour augmenter le nombre ou la taille des nœuds :
# Exemple AWS EKS
aws eks update-nodegroup-config --cluster-name my-cluster --nodegroup-name my-nodegroup --scaling-config minSize=2,maxSize=5,desiredSize=3
Pour les installations sur site, ajoutez un nouveau nœud au cluster.
Surallocation et throttling CPU
Si les pods sont throttlés, vous pouvez observer une utilisation élevée du CPU mais une performance applicative faible. Vérifiez les métriques de throttling CPU (si vous utilisez Prometheus) ou inspectez l’état du pod :
kubectl top pod <pod-name>
Si l’utilisation atteint la limite et que l’application est lente, augmentez la limite CPU ou réduisez la charge parallèle.
Nœud non prêt (NotReady)
Si un nœud devient NotReady, les pods peuvent être replanifiés ailleurs. Vérifiez l’état du nœud et les événements :
kubectl get nodes
kubectl describe node <node-name> | grep -A 5 Conditions
Récupération : examinez l’infrastructure sous-jacente du nœud (disque, réseau, kubelet). S’il ne peut pas être réparé, videz et supprimez le nœud :
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
kubectl delete node <node-name>
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle pour exécuter la planification de capacité comme un processus reproductible. Remplacez les exemples par vos propres valeurs.
- Inventaire de l’état actuel
- Commande :
kubectl get nodes -o wideetkubectl describe nodes | grep -A 5 "Allocated resources" - Attendu : liste des nœuds avec les versions, rôles et pourcentages d’allocation des ressources.
- Responsable : ingénieur plateforme (par exemple, Alex Chen, DevOps Lead)
- Définir les SLO et les cibles de capacité
- Exemple : garantir que 95 % des pods sont planifiés en 30 secondes. Maintenir les demandes de CPU des nœuds sous 70 %, les demandes de mémoire sous 80 %.
- Responsable : product owner et responsable plateforme (par exemple, Maria Lopez, SRE Manager)
- Définir les demandes et limites de ressources sur toutes les charges de travail
- Appliquez LimitRange et ResourceQuota par namespace.
- Commande :
kubectl apply -f policies.yaml - Vérifiez :
kubectl describe limitrange -n team-a
- Surveiller les tendances d’utilisation
- Utilisez Prometheus/Grafana ou
kubectl topchaque semaine. Recherchez une croissance régulière ou des pics. - Exemple d’alerte : si les demandes de mémoire des nœuds dépassent 75 % pendant 1 heure, déclenchez une revue.
- Tester l’autoscaling
- Simulez une augmentation de charge (par exemple, en utilisant
hey -z 5m -c 50 http://service). - Vérifiez que le Cluster Autoscaler monte en charge et que le HPA augmente les réplicas.
- Commande :
kubectl get hpaetkubectl logs -n kube-system cluster-autoscaler
- Planifier les changements de pools de nœuds
- Décidez s’il faut ajouter des nœuds de la même taille ou passer à des types d’instances différents.
- Utilisez des outils de planification de capacité (par exemple, Kubernetes OOMKilled analyzer, KubeCost) pour estimer.
- Documenter les runbooks de récupération
- Pour chaque mode de défaillance (pods en attente, évictions, panne de nœud), ayez une récupération étape par étape.
- Stockez dans un wiki ou un dépôt versionné.
- Révisez trimestriellement.
Conclusion
La planification de la capacité des nœuds Kubernetes n’est pas une tâche ponctuelle mais une pratique continue. En inventoriant votre environnement, en définissant des configurations de ressources sûres, en vérifiant avec des diagnostics et en vous préparant aux défaillances, vous pouvez maintenir un cluster fiable et rentable.
Commencez par une vérification à faible risque : choisissez un seul déploiement, inspectez son utilisation actuelle des ressources, ajustez les demandes et limites pour correspondre aux besoins observés, et surveillez pendant 24 heures. Ensuite, étendez à d’autres charges de travail et mettez en œuvre des quotas et l’autoscaling.
Rappelez-vous : chaque changement doit être versionné, observable et réversible. Documentez ce que vous attendez de voir et ce qu’il faut faire si la réalité diffère. Avec ces pratiques, vous pouvez prévenir les incidents liés à la capacité avant qu’ils n’impactent vos utilisateurs.