Introduction
La planification de capacité dans Kubernetes commence souvent par un problème : un pod est expulsé, un nœud manque de mémoire ou un déploiement ne peut pas être planifié. Les équipes se précipitent alors pour augmenter les limites ou mettre à l'échelle les réplicas sans connaître la consommation réelle des ressources. Résultat : un gaspillage de dépenses cloud ou des incidents répétés.
Cet article fournit un flux de travail pratique, piloté par commandes, pour la planification de capacité avec kubectl. Il couvre comment inspecter l'utilisation actuelle, définir les requêtes et limites de ressources, choisir des stratégies de mise à l'échelle, vérifier les changements et récupérer en cas de problème. Chaque section inclut des commandes concrètes avec les résultats attendus et les signaux d'échec.
Le public cible est constitué de développeurs, d'ingénieurs DevOps et de SRE qui gèrent des charges de travail Kubernetes et souhaitent passer de décisions réactives à une planification proactive fondée sur des preuves.
Inventaire de la version et de l'environnement
Avant de modifier quoi que ce soit, connaissez votre environnement. Vérifiez la version de kubectl et la connectivité du cluster.
kubectl version --short
Exemple de sortie :
Client Version: v1.27.2
Kustomize Version: v5.0.1
Server Version: v1.26.5
Si la version majeure/mineure du client et du serveur diffère de plus d'une version, soyez prudent avec les nouveaux champs d'API. Ensuite, confirmez le contexte et l'espace de noms ciblés.
kubectl config current-context
kubectl get namespaces
Cela évite d'appliquer des changements au mauvais cluster ou espace de noms. Pour la planification de capacité, les composants pertinents sont les Deployments, StatefulSets, DaemonSets et Pods. Identifiez ceux dont les paramètres de ressources sont incertains.
kubectl get pods -o wide --all-namespaces
La sortie montre le placement sur les nœuds, l'état et les redémarrages. Les pods en état Pending ou avec de nombreux redémarrages ont probablement des problèmes de capacité.
Vérification pratique : exécutez kubectl describe pod <nom> -n <namespace> et recherchez des événements comme FailedScheduling avec des messages tels que 0/3 nodes are available: insufficient memory. Cela indique que la requête actuelle dépasse la capacité disponible des nœuds. Notez cela avant de faire tout changement.
Chemin de configuration sûr
Les requêtes et limites de ressources sont la base de la planification de capacité. Les requêtes définissent la quantité garantie de CPU et de mémoire qu'un pod peut utiliser, tandis que les limites plafonnent l'utilisation maximale. Sans elles, le planificateur ne peut pas prendre de décisions éclairées et un voisin bruyant peut consommer toutes les ressources du nœud.
Définissez les requêtes en fonction de l'utilisation observée, pas de suppositions. Le moyen le plus fiable est d'utiliser le Vertical Pod Autoscaler (VPA) en mode recommandation ou d'inspecter les métriques. Commencez par vérifier l'utilisation actuelle :
kubectl top pods -n <namespace>
Exemple de sortie :
NAME CPU(cores) MEMORY(bytes)
nginx-6c8b449f8f-g9f8q 5m 61Mi
redis-68b8d9d5c9-5j4kp 8m 5Mi
Si kubectl top échoue avec Error from server (NotFound): the server could not find the requested resource, le metrics-server n'est pas installé. Installez-le ou utilisez la surveillance du fournisseur cloud.
Pour une application web typique utilisant environ 50m de CPU et 120Mi de mémoire en charge normale, définissez des requêtes avec une petite marge pour couvrir les pics de démarrage : 100m de CPU et 128Mi de mémoire. Les limites peuvent être plus élevées, par exemple 500m de CPU et 512Mi de mémoire, pour permettre des bursts tout en empêchant une consommation incontrôlée.
Exemple d'extrait de Deployment :
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: app
image: nginx:1.25
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
Appliquez-le avec :
kubectl apply -f deployment.yaml -n <namespace>
Après avoir modifié les ressources, effectuez un redémarrage progressif si nécessaire. Certains changements nécessitent la recréation des pods.
kubectl rollout restart deployment/web-app -n <namespace>
Vérifiez l'état du déploiement :
kubectl rollout status deployment/web-app -n <namespace>
Sortie attendue :
deployment "web-app" successfully rolled out
Si le déploiement reste bloqué, les pods peuvent ne pas pouvoir être planifiés avec les nouvelles requêtes. Vérifiez les événements et ajustez.
Vérification et diagnostic
Après avoir appliqué des changements de ressources ou mis à l'échelle, vérifiez que les pods fonctionnent et sont sains. Utilisez les commandes standard :
kubectl get pods -o wide -n <namespace>
Recherchez le statut Running et les colonnes READY indiquant 1/1. Pour une inspection plus approfondie :
kubectl describe pod <nom-du-pod> -n <namespace>
Sections clés dans la sortie de describe :
Conditions:Readydoit êtreTrueContainers.State: doit afficherRunningsans augmentation du nombre de redémarragesEvents: avertissements sur les problèmes de ressources, par exempleOOMKilledsi la limite était trop basse
Pour voir l'utilisation réelle des ressources après un changement :
kubectl top pods -n <namespace>
Comparez l'utilisation avec les requêtes et limites. Si l'utilisation est constamment proche des limites, envisagez d'augmenter les limites ou d'optimiser l'application. Si l'utilisation est bien inférieure aux requêtes, vous surprovisionnez et gaspillez de la capacité.
Pour la vérification au niveau de l'application, utilisez kubectl port-forward pour accéder à un pod localement :
kubectl port-forward pod/<nom-du-pod> 8080:80 -n <namespace>
Ensuite, ouvrez http://localhost:8080 dans un navigateur ou utilisez curl.
Si vous avez modifié le nombre de réplicas, vérifiez la répartition de la charge :
kubectl get endpoints <nom-du-service> -n <namespace>
La sortie attendue inclut les adresses IP de tous les pods prêts. Si certains pods manquent dans les endpoints, ils ne sont pas prêts et ne recevront pas de trafic.
Modes de défaillance et récupération
Les échecs de planification de capacité se répartissent généralement dans ces catégories :
OOMKilled (limite mémoire trop basse)
Lorsqu'un conteneur utilise plus de mémoire que sa limite, le noyau tue le processus avec un code de sortie OOMKilled. Vérifiez l'état du pod :
kubectl get pods -n <namespace>
La sortie montre le nombre de RESTARTS en augmentation et le STATUS comme CrashLoopBackOff. Décrivez le pod :
kubectl describe pod <nom-du-pod> -n <namespace>
Recherchez :
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Récupération : augmentez la limite mémoire d'au moins 20 à 30 % au-dessus du pic d'utilisation observé. Vérifiez également si l'application a une fuite mémoire ; augmenter simplement les limites peut ne faire que reporter le problème.
Limitation CPU (CPU throttling)
Si l'utilisation du CPU atteint la limite, le noyau limite le conteneur, ce qui augmente la latence sans terminaison. Vérifiez les métriques du conteneur :
kubectl top pods -n <namespace>
Si l'utilisation du CPU est égale ou proche de la limite, inspectez la limitation avec kubectl describe sous Conditions ou utilisez le metrics-server avec des outils supplémentaires. Récupération : augmentez la limite CPU ou, si la charge est intermittente, envisagez de définir une limite supérieure à la requête pour permettre des bursts.
Expulsion due à la pression sur le nœud
Si un nœud manque de mémoire, le kubelet expulse les pods selon leur requête/limite et leur priorité. Les pods expulsés montrent le statut Failed avec la raison Evicted. La récupération peut nécessiter une replanification ou l'ajout de capacité. Vérifiez l'état du nœud :
kubectl describe node <nom-du-nœud>
Recherchez la condition MemoryPressure définie sur True. Envisagez ensuite de réduire les requêtes mémoire, de déplacer les pods vers d'autres nœuds ou de faire évoluer le cluster.
Échec de planification
De nouveaux pods peuvent ne pas être planifiés si les requêtes dépassent les ressources disponibles des nœuds. Les événements montrent FailedScheduling avec insufficient cpu ou insufficient memory. Récupération : réduisez les requêtes si elles ont été surestimées, ou ajoutez des nœuds / activez l'autoscaling du cluster.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour effectuer les changements de planification de capacité en toute sécurité. Pour chaque élément, nous nommons un responsable et une fréquence de révision.
| # | Vérification | Commande / Action | Résultat attendu | Responsable | Fréquence de révision |
|---|---|---|---|---|---|
| 1 | Confirmer le contexte et l'espace de noms | kubectl config current-context et kubectl get ns | Cluster et espace de noms corrects | Ingénieur plateforme | À chaque changement |
| 2 | Utilisation de référence | kubectl top pods -n <namespace> | Utilisation CPU/mémoire par pod | Responsable DevOps | Hebdomadaire |
| 3 | Identifier les pods sans requêtes/limites | kubectl get pods -o json \| jq '.items[] | select(.spec.containers[].resources.requests == null) \| .metadata.name' | Liste des pods non conformes | SRE | Mensuel |
| 4 | Définir requêtes/limites dans les manifestes | Modifier YAML et appliquer | Les pods fonctionnent avec des ressources définies | Propriétaire de l'application | À chaque version |
| 5 | Vérifier le déploiement | kubectl rollout status deployment/ -n | successfully rolled out | Responsable des déploiements | À chaque déploiement |
| 6 | Vérifier l'utilisation réelle par rapport aux requêtes | kubectl top pods vs requêtes configurées | Utilisation raisonnable | Responsable DevOps | Hebdomadaire |
| 7 | Tester la récupération après échec | Réduction et augmentation intentionnelles | Les pods se replanifient avec succès | Ingénieur plateforme | Trimestriel |
Pièges courants et comment les éviter
Utiliser des requêtes égales aux limites
Beaucoup d'équipes définissent requêtes = limites par simplicité. Cela garantit la qualité de service mais empêche les bursts CPU et peut gaspiller la mémoire allouée puisque les requêtes mémoire sont comptées dans la capacité du nœud même si elles ne sont pas utilisées. Pour la mémoire, le surcommit est autorisé, mais un surcommit excessif risque des expulsions. Pour le CPU, autorisez une limite supérieure à la requête pour permettre des bursts si nécessaire, mais soyez conscient de la limitation.
Définir des limites sans données historiques
Deviner les besoins en ressources conduit souvent à des OOMKills ou à un gaspillage de capacité. Utilisez des données de surveillance sur au moins deux semaines, couvrant les pics et les heures creuses, avant de définir les valeurs. Des outils comme Prometheus et Grafana peuvent aider à visualiser les tendances.
Ne pas tenir compte du surcoût de démarrage
De nombreuses applications utilisent plus de ressources au démarrage (par exemple, chargement de caches). Définissez les requêtes en fonction de l'utilisation en régime permanent, mais assurez-vous que les limites peuvent absorber le burst de démarrage, ou utilisez une startupProbe pour retarder la disponibilité jusqu'à la fin du burst.
Ignorer l'impact des réplicas sur la capacité des nœuds
Chaque réplica consomme ses requêtes des ressources du nœud. Augmenter les réplicas sans vérifier la capacité des nœuds peut provoquer des échecs de planification. Utilisez kubectl describe nodes pour voir les ressources allouées et les comparer à la capacité.
S'appuyer uniquement sur la mise à l'échelle horizontale
L'Horizontal Pod Autoscaler (HPA) est utile mais ne fonctionne que si les pods ont des requêtes correctement définies. Le HPA répond également lentement par rapport aux pics de trafic. Combinez le HPA avec des marges de ressources raisonnables et, si nécessaire, le Vertical Pod Autoscaler en mode recommandation.
Conclusion
Une planification de capacité efficace avec kubectl ne consiste pas à deviner les limites ; elle consiste à observer l'utilisation réelle, à définir des requêtes et limites fondées sur des preuves, à vérifier les changements et à planifier la récupération. Le flux de travail est :
- Inventorier l'environnement et l'état actuel.
- Établir une référence avec
kubectl top. - Ajuster les requêtes et limites par petits incréments documentés.
- Vérifier le déploiement avec
kubectl rollout statusetkubectl get pods. - Surveiller les OOM kills, la limitation et les expulsions.
- Revoir régulièrement à mesure que les modèles de trafic changent.
En suivant ces pratiques, vous éviterez les pièges courants, réduirez les coûts cloud et maintiendrez la fiabilité des applications. Commencez petit : choisissez un déploiement, appliquez la liste de contrôle et itérez. Votre futur vous, et votre cluster, vous remercieront.