Introduction
La mise à niveau ou la migration de Kubernetes Topology Manager ne se résume pas à changer un numéro de version. Il s’agit d’un changement opérationnel qui peut modifier la façon dont le kubelet aligne les ressources CPU, mémoire et périphériques entre les nœuds NUMA. Une mise à niveau négligente peut entraîner des échecs d’admission des pods, un alignement inattendu des ressources, voire une instabilité du nœud. Ce guide fournit une approche pratique et concrète pour les opérateurs, les ingénieurs DevOps et les équipes plateforme qui doivent planifier, exécuter, vérifier et récupérer après des modifications de Topology Manager.
Nous suivrons un flux de travail complet : inventorier l’environnement actuel, concevoir un chemin de configuration sûr, valider les modifications avant le déploiement, diagnostiquer les échecs et effectuer une restauration si nécessaire. Chaque section comprend des commandes concrètes, des sorties attendues réalistes et des critères de décision. Les exemples supposent un cluster Kubernetes exécutant la version 1.27 ou ultérieure, mais les principes s’appliquent à toute version prise en charge.
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 le résultat et documenter la procédure de récupération si l’état attendu n’est pas atteint.
Inventaire des versions et de l’environnement
Avant de toucher à toute configuration, vous devez savoir exactement ce que vous exécutez. Cette section couvre la collecte des informations nécessaires sur votre version de Kubernetes, la topologie des nœuds, la configuration actuelle de Topology Manager et les composants pertinents.
1. Identifier les versions de Kubernetes et du kubelet
Exécutez la commande suivante sur un nœud du plan de contrôle :
kubectl version --short
Depuis Kubernetes 1.26, l’option --short est dépréciée mais reste largement utilisée. Une sortie typique ressemble à :
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
Sur chaque nœud worker, vérifiez la version du kubelet :
kubelet --version
Exemple de sortie :
Kubernetes v1.27.3
Enregistrez à la fois les versions du plan de contrôle et du kubelet. Le comportement de Topology Manager peut différer selon les versions du kubelet, même si le plan de contrôle est identique.
2. Vérifier la configuration actuelle de Topology Manager
Le fichier de configuration du kubelet se trouve généralement dans /var/lib/kubelet/config.yaml. Inspectez-le pour les champs liés à la topologie :
sudo cat /var/lib/kubelet/config.yaml | grep -A 20 topologyManager
Si Topology Manager n’est pas configuré, vous ne verrez aucune sortie ou les valeurs par défaut suivantes :
topologyManagerPolicy: none
Les autres valeurs possibles sont :
none: Topology Manager désactivé (par défaut)best-effort: aligne les ressources lorsque possible, mais ne rejette jamais les podsrestricted: aligne strictement les ressources, rejette les pods qui ne peuvent pas être alignéssingle-numa-node: identique àrestricted, mais exige en plus que toutes les ressources tiennent sur un seul nœud NUMA (déprécié en 1.27, utilisezrestrictedavectopologyManagerScope: podoucontainer)
Vérifiez également le topologyManagerScope :
topologyManagerScope: container # ou pod
Et la politique du CPU Manager, car Topology Manager interagit avec lui :
cpuManagerPolicy: static
Si vous utilisez un fichier de configuration du kubelet, vérifiez que le kubelet l’utilise réellement. Examinez l’unité systemd du kubelet :
systemctl cat kubelet
Trouvez le drapeau --config. Il doit pointer vers votre fichier. Sinon, le kubelet peut utiliser des drapeaux en ligne de commande, qui ont la priorité. Dans ce cas, vérifiez la ligne de commande :
ps aux | grep kubelet
Recherchez des drapeaux comme --topology-manager-policy et --cpu-manager-policy.
3. Inspecter la topologie NUMA du nœud
Vous devez connaître la disposition NUMA de vos nœuds. Utilisez lscpu sur un nœud :
lscpu | grep -E 'NUMA|CPU\(s\)|On-line'
Exemple de sortie sur un serveur à deux sockets :
CPU(s): 32
On-line CPU(s) list: 0-31
NUMA node(s): 2
NUMA node0 CPU(s): 0-15
NUMA node1 CPU(s): 16-31
Cela indique que le nœud possède deux nœuds NUMA, chacun avec 16 CPU.
4. Vérifier les plugins de périphériques et les ressources
Si vous utilisez des périphériques comme des GPU ou des cartes réseau SR-IOV, listez les ressources étendues sur les nœuds :
kubectl describe nodes | grep -A 5 'Capacity:'
Recherchez des entrées comme nvidia.com/gpu: 2 ou intel.com/sriov: 4. Ces périphériques sont gérés par des plugins de périphériques, et Topology Manager tiendra compte de leur affinité NUMA.
5. Vérifier le comportement actuel de planification des pods
Avant de modifier quoi que ce soit, observez comment les pods actuels sont placés. Pour un pod en cours d’exécution, vous pouvez voir ses CPU et nœuds NUMA attribués :
kubectl get pod <nom-du-pod> -o jsonpath='{.spec.containers[0].resources}'
Pour voir l’attribution réelle des CPU sur le nœud, vous pouvez utiliser crictl (si configuré) ou examiner le cgroup :
sudo crictl inspect <id-du-conteneur> | grep -A 5 cpuset
Cependant, cela n’est souvent pas facilement accessible. Une méthode plus simple consiste à consulter les journaux du kubelet pour les décisions de Topology Manager :
sudo journalctl -u kubelet | grep -i topology
Recherchez des lignes indiquant des indices d’alignement ou des échecs.
Liste de contrôle pratique pour l’inventaire
- [ ] Enregistrer les versions du serveur Kubernetes et du kubelet.
- [ ] Documenter les valeurs actuelles de
topologyManagerPolicyettopologyManagerScope. - [ ] Documenter la politique
cpuManagerPolicyactuelle et les drapeaux associés. - [ ] Capturer la topologie NUMA pour chaque type de nœud.
- [ ] Lister les ressources étendues et les plugins de périphériques.
- [ ] Établir une base de référence du comportement de planification des pods (sélectionner quelques pods représentatifs).
- [ ] Stocker cet inventaire dans un document versionné ou un dépôt Git.
Chemin de configuration sûr
Une fois que vous disposez d’un inventaire complet, planifiez soigneusement les modifications de configuration. Le principe clé est de ne faire qu’un seul changement à la fois et de vérifier son effet avant de continuer.
1. Décider de la configuration cible
Réfléchissez à ce que vous voulez accomplir :
- Migrer de
noneàbest-effort: risque minimal, améliore l’alignement lorsque possible sans rejeter de pods. - Migrer de
noneoubest-effortàrestricted: risque plus élevé ; les pods qui ne peuvent pas être alignés seront rejetés. - Changer
topologyManagerScopedecontaineràpod: peut augmenter la rigueur de l’alignement. - Mettre à niveau Kubernetes : peut apporter de nouvelles fonctionnalités de Topology Manager ou déprécier d’anciennes.
Pour une première étape typique, l’activation de best-effort est une amélioration sûre. Exemple d’extrait de configuration du kubelet :
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
topologyManagerPolicy: best-effort
topologyManagerScope: container
cpuManagerPolicy: static
cpuManagerReconcilePeriod: 10s
2. Choisir un nœud de test
Ne déployez jamais les modifications sur tous les nœuds à la fois. Choisissez un nœud worker qui n’exécute pas de charges de travail critiques ou qui peut tolérer une interruption. Drainez le nœud avant d’apporter des modifications :
kubectl drain <nom-du-nœud> --ignore-daemonsets --delete-emptydir-data
Cela évacue tous les pods du nœud. Le drapeau --delete-emptydir-data est nécessaire si des pods utilisent des volumes emptyDir ; sinon, le drainage restera bloqué.
3. Mettre à jour la configuration du kubelet
Sur le nœud de test, modifiez le fichier de configuration du kubelet (par exemple, /var/lib/kubelet/config.yaml). Faites d’abord une sauvegarde :
sudo cp /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak
Appliquez ensuite vos modifications. Par exemple, pour activer best-effort :
sudo sed -i 's/topologyManagerPolicy: none/topologyManagerPolicy: best-effort/' /var/lib/kubelet/config.yaml
Si la ligne n’existe pas, ajoutez-la sous la section appropriée. Assurez-vous que l’indentation YAML est correcte.
4. Redémarrer le kubelet
Redémarrez le kubelet pour appliquer la nouvelle configuration :
sudo systemctl restart kubelet
Vérifiez qu’il fonctionne :
sudo systemctl status kubelet
Recherchez des messages d’erreur dans le journal :
sudo journalctl -u kubelet --since "5 minutes ago" | grep -i error
5. Décordonner le nœud et tester la planification
Autorisez à nouveau la planification des pods :
kubectl uncordon <nom-du-nœud>
Déployez ensuite un pod de test simple qui demande plusieurs ressources, comme du CPU et de la mémoire, pour voir comment Topology Manager les aligne. Par exemple :
apiVersion: v1
kind: Pod
metadata:
name: topology-test
spec:
containers:
- name: test
image: nginx
resources:
requests:
cpu: "2"
memory: "1Gi"
limits:
cpu: "2"
memory: "1Gi"
Appliquez et vérifiez sa planification :
kubectl apply -f topology-test.yaml
kubectl get pods -o wide
Si le pod est planifié, vérifiez les journaux du kubelet sur le nœud pour les décisions de Topology Manager :
sudo journalctl -u kubelet | grep -i topology | tail -20
Recherchez des messages indiquant des indices d’alignement ou une allocation réussie.
6. Surveiller et comparer
Laissez le pod de test s’exécuter pendant un certain temps et surveillez tout comportement inattendu. Supprimez-le ensuite :
kubectl delete pod topology-test
Comparez le comportement du nœud avant et après le changement. Si tout va bien, passez au nœud suivant, un à la fois.
Vérification et diagnostics
Après avoir appliqué les modifications, vous devez vérifier que Topology Manager applique la politique prévue et que les pods sont planifiés comme attendu. Cette section fournit des commandes et des techniques de diagnostic.
1. Vérifier la configuration active
Sur le nœud, vérifiez la configuration effective du kubelet :
sudo kubectl get --raw /api/v1/nodes/<nom-du-nœud>/proxy/configz | jq '.kubeletconfig.topologyManagerPolicy'
Cela interroge le point de terminaison configz du kubelet (nécessite que le serveur API dispose d’un accès proxy). La sortie doit afficher votre politique configurée, par exemple, "best-effort".
Si configz n’est pas disponible, vérifiez le processus kubelet en cours d’exécution :
ps aux | grep kubelet | grep -o 'topology-manager-policy=[^ ]*'
Si vous utilisez un fichier de configuration, vous pouvez également vérifier le contenu du fichier :
sudo grep topologyManagerPolicy /var/lib/kubelet/config.yaml
2. Tester avec un pod nécessitant un alignement
Déployez un pod avec une qualité de service Garantie (requêtes égales aux limites) et plusieurs ressources :
apiVersion: v1
kind: Pod
metadata:
name: strict-alignment-test
spec:
containers:
- name: test
image: nginx
resources:
requests:
cpu: "4"
memory: "4Gi"
ephemeral-storage: "1Gi"
limits:
cpu: "4"
memory: "4Gi"
ephemeral-storage: "1Gi"
Ce pod demande une quantité spécifique de CPU et de mémoire qui doit être alignée. Appliquez et vérifiez s’il est planifié :
kubectl apply -f strict-alignment-test.yaml
kubectl get pods -o wide
Si la politique est restricted et que le nœud ne peut pas satisfaire l’alignement, le pod restera à l’état Pending. Vérifiez les événements du pod pour un message détaillé :
kubectl describe pod strict-alignment-test
Recherchez un événement comme :
Warning FailedScheduling 10s default-scheduler 0/3 nodes are available: 3 node(s) had untolerated taint {node.kubernetes.io/not-ready: }, 3 node(s) didn't match Pod's node affinity/selector.
Ou, si le planificateur l’a autorisé mais que le kubelet l’a rejeté :
Warning Failed 12s kubelet admission failed: topology manager policy "restricted" cannot allocate resources
3. Inspecter les journaux du kubelet pour les décisions de topologie
Sur le nœud, utilisez journalctl pour voir les journaux détaillés :
sudo journalctl -u kubelet --since "10 minutes ago" | grep -i topology
Pour une allocation réussie, vous pourriez voir :
I0523 10:15:32.123456 12345 topology_manager.go:215] [topologymanager] Topology Manager policy best-effort, hints: {01 true}
Pour un échec sous restricted :
E0523 10:20:11.654321 12345 topology_manager.go:187] [topologymanager] Topology Manager policy restricted, unable to find aligned resources for container test
4. Utiliser Node Resource Topology (si disponible)
Kubernetes 1.27+ peut avoir l’API Node Resource Topology activée. Vous pouvez l’interroger pour voir la disponibilité des ressources par nœud NUMA :
kubectl get noderesourcetopologies
Exemple de sortie :
NAME AGE
node-1 5d
node-2 5d
Décrivez-en un :
kubectl describe noderesourcetopologies node-1
Recherchez les sections topologyPolicies et zones pour comprendre la disposition NUMA et les ressources.
Si cette API n’est pas activée, vous pouvez toujours inspecter l’allocation des ressources du nœud via le point de terminaison /metrics du kubelet pour container_resources_cpu_usage, mais cela est moins spécifique à la topologie.
5. Liste de contrôle de diagnostic
- Confirmer que le kubelet utilise la configuration prévue.
- Déployer un pod de test nécessitant un alignement et observer sa planification.
- Vérifier les événements du pod et les journaux du kubelet pour les messages liés à la topologie.
- Si le pod est rejeté, comprendre pourquoi (distribution des ressources, politique trop stricte).
- Si le pod est accepté, vérifier l’attribution réelle CPU/NUMA (si possible via le cpuset du cgroup).
- Comparer le comportement entre les nœuds si vous avez plusieurs types de nœuds.
Modes de défaillance et récupération
Quelle que soit votre prudence, des problèmes peuvent survenir. Cette section couvre les scénarios de défaillance courants et comment s’en remettre.
1. Le kubelet ne démarre pas après un changement de configuration
Symptôme : Après avoir modifié le fichier de configuration et redémarré le kubelet, le nœud devient NotReady.
Diagnostic : Vérifiez l’état et les journaux du kubelet :
sudo systemctl status kubelet
sudo journalctl -u kubelet --since "5 minutes ago"
Les erreurs possibles incluent un YAML mal formé ou une valeur de politique invalide.
Récupération : Restaurez la configuration de sauvegarde :
sudo cp /var/lib/kubelet/config.yaml.bak /var/lib/kubelet/config.yaml
sudo systemctl restart kubelet
Attendez que le nœud redevienne Ready :
kubectl get nodes
2. Les pods ne sont pas planifiés ou sont évincés
Symptôme : Après avoir activé restricted ou changé la portée, certains pods passent à Pending ou sont évincés.
Diagnostic : Vérifiez les événements du pod :
kubectl describe pod <nom-du-pod>
Recherchez des messages concernant une inadéquation du Topology Manager ou des ressources insuffisantes.
Récupération : Si les pods sont critiques, revenez à la politique best-effort ou none sur le(s) nœud(s) affecté(s), en suivant la même procédure de drainage et de cordon. Ajustez également les requêtes de ressources du pod pour qu’elles soient alignables.
3. Dégradation des performances due à un alignement sous-optimal
Symptôme : Les applications s’exécutent plus lentement après le changement, peut-être parce qu’elles sont désormais épinglées à un seul nœud NUMA et ne peuvent pas utiliser la mémoire distante.
Diagnostic : Comparez les métriques des applications avant et après. Vérifiez si le pod est restreint à un seul nœud NUMA (en utilisant le cpuset du cgroup).
Récupération : Envisagez d’utiliser best-effort au lieu de restricted pour plus de flexibilité. Ou ajustez les ressources du pod pour qu’elles tiennent dans un nœud NUMA si vous souhaitez un alignement strict.
4. Problèmes de compatibilité des plugins de périphériques
Symptôme : Les pods demandant des GPU ou d’autres périphériques ne sont pas planifiés après le changement de Topology Manager.
Diagnostic : Vérifiez les journaux du plugin de périphériques et du kubelet pour les erreurs. Le plugin peut ne pas prendre en charge correctement les indices de topologie.
Récupération : Mettez à jour le plugin de périphériques vers une version qui prend en charge Topology Manager. Ou désactivez Topology Manager pour les pods utilisant ces périphériques en utilisant un espace de noms ou une annotation différente (si pris en charge).
5. Comportement incohérent entre les nœuds
Symptôme : Certains nœuds acceptent des pods tandis que d’autres les rejettent, même s’ils ont des spécifications similaires.
Diagnostic : Vérifiez les différences de topologie NUMA. Certains nœuds peuvent avoir un nombre différent de nœuds NUMA ou une distribution des ressources variée.
Récupération : Standardisez le matériel des nœuds ou ajustez la politique par type de nœud. Vous pouvez utiliser des overrides de configuration du kubelet par groupe de nœuds (par exemple, via des étiquettes de nœud et des fichiers de configuration séparés).
Stratégies générales de récupération
- Toujours garder une sauvegarde de la configuration du kubelet avant les modifications.
- Apporter les modifications un nœud à la fois pour limiter l’impact.
- Disposer d’une méthode pour drainer et cordonner rapidement les nœuds.
- Documenter la procédure exacte de retour en arrière.
- Tester la restauration sur un nœud hors production d’abord, si possible.
Pièges courants et comment les éviter
Cette section met en évidence les erreurs fréquentes et fournit des conseils pour les prévenir ou s’en remettre.
1. Ne pas vérifier la topologie NUMA matérielle avant d’activer des politiques strictes
Piège : Activer restricted ou single-numa-node sur des nœuds avec plusieurs nœuds NUMA sans comprendre la distribution des ressources peut entraîner de nombreux rejets de pods.
Comment éviter : Utilisez lscpu pour cartographier les nœuds NUMA et les CPU. Testez d’abord avec best-effort et surveillez le succès de l’alignement.
Récupération : Revenez à best-effort si trop de pods échouent.
2. Ignorer la configuration du kubelet via les drapeaux de ligne de commande
Piège : Modifier le fichier de configuration sans se rendre compte que le kubelet utilise des drapeaux en ligne de commande qui remplacent le fichier.
Comment éviter : Vérifiez ps aux | grep kubelet et l’unité systemd pour --config versus les drapeaux individuels. Utilisez une seule méthode de manière cohérente.
Récupération : Mettez à jour les drapeaux ou supprimez-les et fiez-vous au fichier de configuration.
3. Appliquer les modifications à tous les nœuds à la fois
Piège : Déployer un changement de Topology Manager dans tout le cluster sans test canari peut provoquer des échecs de planification généralisés.
Comment éviter : Utilisez un déploiement progressif : un nœud à la fois, surveillez, puis continuez. Envisagez d’utiliser des pools de nœuds ou des déploiements de machines pour gérer différentes configurations.
Récupération : Si vous avez déjà déployé sur de nombreux nœuds, drainez et revenez rapidement sur chaque nœud, ou utilisez un outil de gestion de configuration pour pousser l’ancienne configuration.
4. Négliger l’impact sur les pods Garantis
Piège : Les pods avec une qualité de service Garantie (requêtes égales aux limites) sont toujours pris en compte pour un alignement strict. Si vous activez restricted, tous ces pods doivent être alignables.
Comment éviter : Avant l’activation, passez en revue les pods Garantis existants et leurs requêtes de ressources. Déterminez s’ils peuvent tenir dans les contraintes NUMA.
Récupération : Ajustez les ressources du pod ou utilisez best-effort si l’alignement n’est pas critique.
5. Ne pas tenir compte de l’interaction avec la politique du CPU Manager
Piège : Topology Manager travaille en étroite collaboration avec CPU Manager. Si la politique du CPU Manager est none, Topology Manager a un effet limité pour le CPU.
Comment éviter : Décidez de la politique du CPU Manager (static est recommandé pour un alignement strict) et configurez-la avec Topology Manager.
Récupération : Assurez-vous que les deux politiques sont cohérentes.
6. Oublier de vérifier les ressources étendues et les plugins de périphériques
Piège : Les périphériques comme les GPU peuvent avoir leurs propres indices de topologie. Si le plugin est obsolète ou mal configuré, Topology Manager peut ne pas recevoir d’indices corrects.
Comment éviter : Mettez à jour les plugins de périphériques vers des versions qui prennent en charge Topology Manager. Testez avec des périphériques factices si possible.
Récupération : Désactivez Topology Manager pour les pods utilisant des périphériques ou mettez à jour le plugin.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle pour assurer une mise à niveau ou une migration fluide. Chaque élément inclut un responsable (une seule personne responsable) et une fréquence de révision.
| # | Tâche | Responsable | Fréquence / Date de révision |
|---|---|---|---|
| 1 | Inventorier les versions actuelles de Kubernetes/kubelet, la configuration de topologie et la disposition NUMA | Priya Shah, ingénieure plateforme | Avant chaque changement ; audit trimestriel |
| 2 | Décider de la politique et de la portée cibles de Topology Manager | Marcus Chen, responsable ingénierie | Par cycle de mise à niveau |
| 3 | Sélectionner un nœud de test et le drainer | Priya Shah | Par déploiement |
| 4 | Sauvegarder la configuration du kubelet et appliquer les modifications sur le nœud de test | Priya Shah | Par nœud |
| 5 | Redémarrer le kubelet et vérifier l’état | Priya Shah | Immédiatement après le changement |
| 6 | Décordonner le nœud et déployer un pod de test pour valider la planification | Marcus Chen | Après que le nœud est prêt |
| 7 | Surveiller les journaux du kubelet et les événements du pod pour les décisions de topologie | Priya Shah | En continu pendant le pilote |
| 8 | En cas de succès, passer au nœud suivant un par un | Marcus Chen | Quotidiennement pendant le déploiement |
| 9 | En cas d’échec, exécuter la procédure de retour en arrière documentée | Priya Shah | Au besoin |
| 10 | Documenter les résultats et mettre à jour les procédures opérationnelles | Priya Shah | Après chaque changement ; révision mensuelle |
Conclusion
La mise à niveau ou la migration de Kubernetes Topology Manager est une opération délicate qui nécessite une planification minutieuse, une exécution incrémentale et une vérification approfondie. En suivant les procédures de ce guide - de l’inventaire initial à la configuration sûre, en passant par la validation, les diagnostics et la récupération - vous pouvez minimiser les risques et obtenir un meilleur alignement des ressources dans votre cluster.
N’oubliez pas que chaque cluster est différent, et ce qui fonctionne dans un environnement peut ne pas fonctionner dans un autre. Testez toujours d’abord dans un environnement de préproduction ou canari, et ayez un plan de retour en arrière solide. Gardez vos configurations de kubelet sous contrôle de version et documentez chaque changement.
Comme prochaine étape, choisissez une vérification à faible risque (par exemple, activer best-effort sur un seul nœud) et suivez la liste de contrôle. Enregistrez l’état actuel, exécutez le changement, comparez le comportement attendu et réel, et examinez les dépendances telles que CPU Manager, les plugins de périphériques et les politiques de planification. Avec une approche méthodique, vous pouvez tirer parti de Topology Manager en toute sécurité pour améliorer les performances des charges de travail et l’utilisation des ressources.