## Introduction Kustomization est une fonctionnalité intégrée puissante de Kubernetes pour gérer les manifestes sans modèles. Elle permet aux opérateurs de déclarer des variations d'une configuration de base pour différents environnements. Cependant, à mesure que le nombre de surcouches, de correctifs et de ressources augmente, les performances de Kustomization peuvent se dégrader, entraînant des builds plus lents, des déploiements retardés et une charge accrue sur le serveur API. Ce guide propose une approche pratique et concrète pour diagnostiquer et optimiser les problèmes de performance de Kustomization. Cet article s'adresse aux développeurs, ingénieurs DevOps et équipes techniques de startups qui utilisent Kustomize et doivent résoudre des goulots d'étranglement de latence ou optimiser leur pipeline de configuration. En suivant les étapes décrites ici, vous apprendrez à observer le comportement actuel, à apporter des modifications contrôlées et à vérifier les améliorations à l'aide de commandes concrètes et de résultats attendus. Le principe directeur est la sécurité opérationnelle : ne faites pas de changements à l'aveugle. Établissez plutôt une base de référence, comprenez le rayon d'impact de toute modification, évitez d'exposer des secrets et ayez un plan de récupération clair si un changement ne produit pas le résultat escompté. ## Inventaire des versions et de l'environnement Avant de tenter toute optimisation des performances, vous devez connaître précisément votre environnement. Cette section couvre les informations essentielles à collecter. ### Ce qu'il faut enregistrer - **Version de Kubectl** : `kubectl version --client --output=yaml` et `kubectl version --server --output=yaml` (si vous avez un accès direct au plan de contrôle). - **Version de Kustomize** : `kubectl kustomize version` (si vous utilisez le kustomize intégré à kubectl) ou `kustomize version` si vous avez le binaire autonome. - **Version et topologie du cluster** : la version du serveur Kubernetes, le nombre de nœuds, les points de terminaison du plan de contrôle, et si vous utilisez un service managé (EKS, GKE, AKS) ou un cluster auto-géré. - **Outillage de déploiement** : quels outils sont utilisés pour appliquer les Kustomizations, comme Argo CD, Flux ou simplement `kubectl apply -k`. - **Nombre de ressources** : combien de ressources sont générées par Kustomization, et combien de Kustomizations existent au total. ### Exemples de commandes d'inventaire Exécutez d'abord ces commandes en lecture seule pour capturer l'état actuel : ```bash # Sauvegarder l'état actuel pour comparaison ultérieure kubectl get nodes -o wide > nodes-avant.txt kubectl get pods -A -o wide > pods-avant.txt kubectl get kustomizations -A -o yaml > kustomizations-avant.yaml # si vous utilisez Flux kubectl get applications -A -o yaml > applications-avant.yaml # si vous utilisez Argo CD ``` Vérifiez la version de Kustomize : ```bash kubectl kustomize version # Exemple de sortie : # v4.5.7 ``` Si vous utilisez un binaire `kustomize` autonome : ```bash kustomize version # Exemple de sortie : # {Version:kustomize/v4.5.7 GitCommit:56d82a8378dfc8dc3b3b1085e5a6e67b82966bd7 BuildDate:2022-08-02T16:35:54Z GoOs:linux GoArch:amd64} ``` ### Identifier la base de référence Choisissez une Kustomization spécifique qui présente des performances lentes. Par exemple, supposons que vous ayez une Kustomization pour une application web avec 200 ressources (Déploiements, Services, ConfigMaps, etc.). Enregistrez les temps de build et d'application actuels : ```bash # Chronométrer le build kustomize (autonome) time kustomize build ./chemin/vers/overlay > /tmp/sortie.yaml # Exemple de sortie : # real 0m12.344s # user 0m10.121s # sys 0m1.223s # Chronométrer l'application avec kubectl et kustomize kubectl create namespace test-ns --dry-run=client -o yaml | kubectl apply -f - time kubectl apply -k ./chemin/vers/overlay -n test-ns ``` Si vous utilisez Argo CD ou Flux, consultez la durée de réconciliation dans l'interface utilisateur ou les journaux. ### Prérequis et contraintes - Vous avez besoin de `kubectl` configuré avec les droits cluster-admin ou au moins les permissions de lecture sur toutes les ressources de l'espace de noms que vous testez. - Assurez-vous de ne pas tester sur un cluster de production sans garde-fous appropriés. Utilisez un espace de noms de test dédié ou un cluster de préproduction. - Les performances de Kustomize peuvent être affectées par le nombre de fichiers, la complexité des transformateurs et la latence réseau vers le serveur API. Avant de modifier quoi que ce soit, comprenez les limites de votre environnement (par exemple, CPU et mémoire du runner CI ou du contrôleur). ## Chemin de configuration sûr Une fois que vous avez une base de référence, l'étape suivante consiste à apporter de petites modifications incrémentales et à mesurer leur impact. Cette section décrit une approche sûre pour optimiser les performances de Kustomization. ### Observer avant d'intervenir Ne changez jamais plusieurs variables à la fois. Si vous soupçonnez qu'un transformateur ou une fonctionnalité spécifique cause la lenteur, testez-le isolément. Par exemple, si vous utilisez un grand nombre de correctifs (`patchesStrategicMerge` ou `patches`), mesurez le temps de build avec et sans ces correctifs. **Exemple** : Supposons que votre surcouche contienne un `kustomization.yaml` avec : ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base patchesStrategicMerge: - patch.yaml - patch2.yaml # ... beaucoup d'autres ``` Mesurez le temps de build : ```bash time kustomize build . > /dev/null ``` Ensuite, commentez temporairement les correctifs (ou déplacez-les dans un répertoire séparé) et mesurez à nouveau. Si le temps de build diminue significativement, vous avez trouvé un facteur contributif. ### Changement minimal justifié Si les correctifs sont nécessaires, envisagez des façons alternatives de les appliquer. Par exemple, utilisez le champ plus récent `patches` avec des sélecteurs de cible explicites au lieu de `patchesStrategicMerge`, ou combinez plusieurs correctifs en un seul pour réduire les entrées/sorties de fichiers. Vérifiez également si un correctif est redondant car il est déjà inclus dans la base. **Exemple** : Convertir de `patchesStrategicMerge` en `patches` en ligne : Avant : ```yaml patchesStrategicMerge: - deployment-patch.yaml ``` Après : ```yaml patches: - target: kind: Deployment name: web patch: |- - op: replace path: /spec/replicas value: 3 ``` Cela réduit les lectures de fichiers et peut accélérer les builds. ### Vérifier le résultat Après avoir apporté une modification, reconstruisez et mesurez le temps. Vérifiez également que la sortie générée est correcte en la comparant avec l'originale (en utilisant `diff` ou `kubectl diff`). ```bash time kustomize build . > /tmp/nouvelle-sortie.yaml kubectl diff -k . -n test-ns ``` Si le diff est propre (aucun changement inattendu) et que le temps de build s'est amélioré, le changement est sûr. ### Chemin de récupération Si le changement cause des problèmes (par exemple, une sortie incorrecte ou un temps de build plus long), revenez immédiatement à la configuration précédente. Puisque vous utilisez un contrôle de version, cela devrait être un simple `git revert`. Validez toujours votre état de travail avant d'expérimenter. ## Vérification et diagnostics Cette section approfondit les techniques de diagnostic pour identifier les goulots d'étranglement de performance des Kustomizations. ### Profilage du build Kustomize Les performances du build Kustomize peuvent être profilées à l'aide du profilage intégré de Go si vous avez le binaire autonome. Exécutez : ```bash kustomize build --profile ./cpu.pprof . > /dev/null go tool pprof -http=:8080 ./cpu.pprof ``` Cela ouvrira une interface web montrant l'utilisation du CPU par fonction, vous aidant à identifier les points chauds (par exemple, les opérations de copie profonde, l'analyse YAML, les boucles de transformateurs). Si vous ne pouvez pas utiliser le profilage, utilisez une approche plus simple : retirez progressivement des parties de la configuration pour isoler le composant lent. Par exemple, commencez avec seulement le champ `resources`, puis ajoutez les générateurs, puis les transformateurs, en mesurant le temps à chaque étape. ### Mesurer la charge du serveur API Les performances de Kustomization affectent également le côté application. Lorsque vous exécutez `kubectl apply -k`, kustomize construit le manifeste puis l'envoie au serveur API. Si le manifeste est volumineux, l'application peut être lente. Vérifiez les métriques du serveur API pour la latence des requêtes et la taille des requêtes. Si vous avez accès aux métriques du plan de contrôle Kubernetes (par exemple, via Prometheus), surveillez : - `apiserver_request_duration_seconds` - `apiserver_request_total` - `apiserver_response_sizes_bytes` Un pic dans ces métriques lors d'une application indique un manifeste volumineux ou complexe. Pour réduire la taille du manifeste, envisagez d'utiliser l'application côté serveur (`server-side apply`) ou de diviser la Kustomization en parties plus petites. L'application côté serveur envoie un correctif plutôt que l'objet complet, ce qui peut réduire la taille de la charge utile. ### Journaux et événements Lors de l'utilisation d'outils GitOps comme Flux ou Argo CD, consultez leurs journaux pour la durée de réconciliation ou les erreurs : ```bash kubectl logs -n flux-system deploy/source-controller | grep -i kustomize # ou pour Argo CD : kubectl logs -n argocd deploy/argocd-repo-server | grep -i kustomize ``` Ces journaux montrent souvent le temps pris pour l'étape de build. Par exemple, les journaux du `kustomize-controller` de Flux incluent un champ `duration` pour chaque réconciliation. ## Modes de défaillance et récupération Comprendre les modes de défaillance courants vous aide à récupérer rapidement lorsque quelque chose tourne mal. ### Timeout de build ou mémoire insuffisante (OOM) Si le build kustomize prend trop de temps ou manque de mémoire, cela peut être dû à un nombre extrêmement élevé de ressources ou à une boucle infinie causée par un `configMapGenerator` ou un `secretGenerator` mal configuré. Par exemple, un `configMapGenerator` avec un motif glob qui correspond à des milliers de fichiers peut provoquer une utilisation mémoire élevée. **Récupération** : Réduisez la portée du générateur. Utilisez des noms de fichiers spécifiques au lieu de jokers, ou divisez la configuration en plusieurs Kustomizations. ### Sortie incohérente entre les builds Parfois, kustomize produit une sortie différente pour la même entrée en raison de l'ordre des cartes ou de fonctionnalités héritées. Cela peut causer des diffs inutiles et des applications répétées. Assurez-vous d'utiliser une version cohérente de kustomize et n'activez `--load-restrictor LoadRestrictionsRootOnly` que si nécessaire, car cela peut affecter le chargement des fichiers. ### L'application échoue avec des limites de ressources Si le manifeste généré dépasse la taille maximale des requêtes du serveur API (par défaut ~3 Mo), l'application échouera avec `413 Request Entity Too Large`. Cela arrive souvent avec de gros ConfigMaps ou Secrets. **Récupération** : Divisez la Kustomization ou utilisez `kubectl create` avec l'application côté serveur pour découper la requête en plus petits morceaux. Alternativement, stockez les données volumineuses dans un volume CSI ou utilisez un autre mécanisme. ### Ordre incorrect des ressources Kustomize peut ne pas appliquer les ressources dans l'ordre souhaité, ce qui peut causer des échecs temporaires. Utilisez `kubectl apply --server-side` avec des gestionnaires de champs ou ajoutez des annotations de `configuration` pour définir les dépendances. ## Liste de contrôle opérationnelle Utilisez cette liste de contrôle pour optimiser et maintenir systématiquement les performances des Kustomizations. | Élément | Responsable | Fréquence | Commande de vérification | Résultat attendu | |---|---|---|---|---| | Enregistrer les versions de kustomize et kubectl | Responsable DevOps (par ex., Priya Shah) | Mensuellement ou après toute mise à niveau | `kustomize version && kubectl version --short` | La sortie correspond à la base documentée | | Mesurer le temps de build pour les Kustomizations représentatives | Ingénieur CI/CD | Hebdomadairement | `time kustomize build ./overlay` | Temps de build dans le SLO (par ex., < 10 s pour 200 ressources) | | Vérifier la taille des requêtes du serveur API lors des applications | Ingénieur plateforme | Avant chaque version | Requête Prometheus : `apiserver_response_sizes_bytes{verb="PATCH"}` | < 1 Mo par requête | | Auditer l'utilisation des générateurs (configMapGenerator, secretGenerator) | Responsable sécurité | Trimestriellement | Examiner les fichiers kustomization pour les jokers ; test `kustomize build --load-restrictor LoadRestrictionsRootOnly` | Aucun fichier inattendu inclus | | Tester la procédure de bascule et de récupération | SRE | Semestriellement | Simuler une application échouée et un retour en arrière ; documenter les étapes | Le retour en arrière se termine en moins de 10 minutes | | Nettoyer les ressources et correctifs inutilisés | Développeurs | Mensuellement | `kustomize build` puis `kubectl diff` pour repérer les ressources supprimées | Aucune ressource orpheline dans le cluster | ## Pièges courants et comment les éviter ### Ignorer la compatibilité des versions **Piège** : Utiliser un `kustomization.yaml` avec des fonctionnalités qui ne sont pas prises en charge par votre version de kustomize, entraînant des erreurs de build ou un repli silencieux. **Pourquoi cela arrive** : Différentes versions de kustomize ont des implémentations de transformateurs et des dépréciations différentes. Par exemple, `patchesStrategicMerge` a été déprécié au profit de `patches` dans kustomize v4+. **Comment éviter** : Épinglez votre version de kustomize dans le CI/CD et l'outillage local. Consultez toujours les notes de version lors d'une mise à niveau. Exécutez un test de build dans un pipeline CI avec la version exacte. ### Utilisation excessive de bases distantes **Piège** : Utiliser des bases distantes (par exemple, des URL GitHub) dans `resources` peut ralentir les builds en raison du téléchargement réseau et du manque de cache. **Pourquoi cela arrive** : Les bases distantes sont pratiques mais introduisent de la latence et des points de défaillance potentiels. **Comment éviter** : Fournissez les bases distantes dans votre dépôt et référencez-les localement. Si vous devez utiliser des bases distantes, configurez un proxy de cache ou utilisez un outil comme `kustomize build` avec `--load-restrictor LoadRestrictionsNone` uniquement dans des environnements de confiance. ### Utilisation excessive de transformateurs **Piège** : Utiliser de nombreux transformateurs `namePrefix`, `nameSuffix`, `commonLabels` et `images` peut augmenter l'utilisation du CPU, surtout sur de grands ensembles de ressources. **Pourquoi cela arrive** : Chaque transformateur itère sur toutes les ressources, et les transformations complexes de noms d'images impliquent l'analyse de chaînes et des recherches dans des cartes. **Comment éviter** : Combinez les transformateurs lorsque c'est possible et appliquez-les au niveau de base au lieu de les répéter dans chaque surcouche. Pour les mises à jour d'images, utilisez `kustomize edit set image` avec parcimonie ou un outil comme `kustomize-sops` pour gérer les balises d'images. ### Ne pas mesurer avant et après **Piège** : Apporter des modifications basées sur des suppositions et ne pas vérifier l'amélioration. **Pourquoi cela arrive** : Il est tentant d'appliquer des bonnes pratiques connues sans tester leur impact dans votre contexte spécifique. **Comment éviter** : Exécutez toujours des expériences contrôlées : changez une variable, mesurez le temps de build et d'application, comparez avec la base de référence, et conservez ou annulez en fonction des données. Utilisez un script ou un job CI pour automatiser cela. ### Construire à chaque commit sans mise en cache **Piège** : Dans un pipeline GitOps, reconstruire toute la Kustomization pour chaque commit gaspille du CPU et ralentit la réconciliation. **Pourquoi cela arrive** : De nombreux contrôleurs (par exemple, Flux) reconstruisent lorsque la source change, mais si la source inclut des fichiers inutilisés ou que le build n'est pas optimisé, cela devient lent. **Comment éviter** : Utilisez `.sourceignore` ou `.kustomizeignore` pour exclure les fichiers non pertinents. Activez la mise en cache du contrôleur si disponible. Divisez les grandes Kustomizations en plus petites qui peuvent être réconciliées indépendamment. ## Conclusion L'optimisation des performances des Kustomizations Kubernetes nécessite une approche méthodique : collecter les données de version et d'environnement, établir une base de référence, apporter des modifications minimales, vérifier les résultats et avoir des plans de récupération. Les commandes concrètes et les exemples de ce guide devraient vous aider à passer du problème observé au résultat vérifié. Pour commencer à améliorer les performances de vos Kustomizations dès aujourd'hui, choisissez une vérification à faible risque dans la liste de contrôle opérationnelle et exécutez-la dans un espace de noms de test. Enregistrez les métriques avant et après pour le temps de build et la charge du serveur API. Partagez vos conclusions avec votre équipe et documentez tout ajustement à votre processus d'optimisation. Un flux de travail opérationnel fiable rend les performances visibles, limite les risques et garantit que chaque changement est fondé sur des preuves. Avec ces pratiques, vous pouvez garder vos déploiements Kubernetes rapides et stables.