## Introduction Lorsqu'une configuration de déploiement ou de service Kubernetes dérive de manière inattendue, Server-Side Apply (SSA) change la façon dont vous suivez et corrigez le problème. Au lieu de deviner quel client a modifié un champ en dernier, SSA enregistre la propriété des champs et les métadonnées de conflit, ce qui facilite l'isolement et la réparation des erreurs de configuration réseau. Ce guide montre comment dépanner le réseau Kubernetes dans un cluster géré par SSA à l'aide de commandes concrètes, de sorties attendues et d'étapes de récupération. L'article s'adresse aux développeurs, aux ingénieurs DevOps et aux équipes techniques de startups qui exploitent des clusters Kubernetes avec SSA activé. Il couvre les points de friction réseau les plus courants : résolution DNS, incohérences de ports, connectivité inter-pods et comportement des politiques réseau. Chaque section commence par une observation en lecture seule de l'état actuel, passe à un changement minimal et se termine par une commande de vérification qui prouve que la correction a fonctionné. Les principes opérationnels tout au long du guide sont simples : observer avant de modifier, limiter le rayon d'impact, ne jamais mettre de secrets dans les manifestes, vérifier le résultat et documenter une procédure de retour en arrière avant d'en avoir besoin. ## Inventaire des versions et de l'environnement Avant de toucher à une configuration réseau, établissez les versions exactes et les composants en jeu. Commencez par confirmer la version du serveur Kubernetes et les capacités de l'API. ### Vérifier le support de SSA SSA est devenu stable dans Kubernetes 1.22, mais les versions antérieures peuvent l'activer avec une porte de fonctionnalité. Vérifiez la version du serveur : ```bash kubectl version --short ``` La sortie attendue ressemble à : ```text Client Version: v1.27.3 Kustomize Version: v5.0.1 Server Version: v1.27.3 ``` Si la version du serveur est 1.22 ou supérieure, SSA est disponible par défaut. Pour confirmer que SSA est actif pour la commande `apply` : ```bash kubectl apply --server-side --dry-run=server -f deployment.yaml ``` L'absence d'erreur indique un support. Pour les clusters plus anciens, vérifiez la porte de fonctionnalité : ```bash kubectl get --raw /metrics | grep server_apply ``` Si la métrique est absente ou nulle, SSA peut ne pas être activé. ### Vérifier les composants réseau de base Le réseau dans Kubernetes dépend de plusieurs composants. Identifiez le plugin CNI utilisé : ```bash kubectl get pods -n kube-system | grep -E 'calico|flannel|weave|cilium|aws-node|azure-cni' ``` Par exemple, un cluster basé sur Calico affiche : ```text calico-node-4x7jz 1/1 Running 0 12d calico-kube-controllers-7c8c9c4d56-8p5vz 1/1 Running 0 12d ``` Si vous utilisez un service géré, le CNI peut ne pas s'exécuter sous forme de pods. Vérifiez le statut du nœud pour l'annotation CNI : ```bash kubectl get nodes -o jsonpath='{.items[0].metadata.annotations}' ``` Recherchez des clés comme `cni.projectcalico.org/podIP` ou similaires. ### Inspecter les objets réseau gérés par SSA Listez les ressources réseau gérées par SSA : ```bash kubectl get services,endpoints,ingresses -o wide ``` Notez la colonne `MANAGED FIELDS` si présente ; avec `kubectl get`, vous pouvez la demander explicitement : ```bash kubectl get service my-service -o yaml | grep -A 5 managedFields ``` Une entrée typique montre le gestionnaire et l'opération : ```yaml managedFields: - manager: kubectl operation: Apply apiVersion: v1 time: "2024-03-26T10:11:12Z" fieldsType: FieldsV1 fieldsV1: f:spec: f:ports: {} ``` Cela confirme que SSA suit le champ. Si un champ n'a pas de propriétaire, des conflits apparaîtront plus tard. ## Chemin de configuration sécurisé Modifier les paramètres réseau avec SSA nécessite une séquence contrôlée : enregistrer l'état actuel, appliquer un changement minimal, vérifier et revenir en arrière si nécessaire. ### Capturer l'état actuel Avant tout changement, sauvegardez l'objet en direct dans un fichier de sauvegarde en utilisant `kubectl get` avec sortie YAML : ```bash kubectl get service my-service -o yaml > service-backup-$(date +%Y%m%d-%H%M%S).yaml ``` Exécutez également `kubectl diff` pour prévisualiser les changements exacts que SSA apporterait sans les appliquer : ```bash kubectl diff -f updated-service.yaml ``` Si le diff est vide, votre fichier local correspond à l'objet en direct. Si vous voyez des lignes commençant par `+` ou `-`, ce sont les changements. ### Appliquer un changement SSA minimal Supposons que vous deviez changer le port d'un service de 80 à 8080. L'extrait YAML d'origine : ```yaml spec: ports: - name: http port: 80 targetPort: 80 ``` Modifiez uniquement le champ `targetPort` : ```yaml spec: ports: - name: http port: 80 targetPort: 8080 ``` Appliquez avec Server-Side Apply et spécifiez explicitement le gestionnaire de champs : ```bash kubectl apply --server-side --field-manager=network-fix -f updated-service.yaml ``` Sortie attendue : ```text service/my-service serverside-applied ``` Si un autre gestionnaire possède le champ `targetPort`, vous verrez un conflit : ```text error: Apply failed with 1 conflict: conflict with "other-manager": .spec.ports[0].targetPort ``` Pour résoudre, vous pouvez forcer la propriété avec `--force-conflicts`, mais seulement après avoir vérifié que c'est sûr : ```bash kubectl apply --server-side --field-manager=network-fix --force-conflicts -f updated-service.yaml ``` Utilisez `--force-conflicts` avec parcimonie ; il transfère la propriété du champ à vous et peut écraser des changements intentionnels d'une autre équipe. ### Vérifier le changement Après l'application, vérifiez l'objet en direct : ```bash kubectl get service my-service -o yaml | grep -A 3 ports ``` Vous devriez voir `targetPort: 8080`. Confirmez également que les endpoints ont été mis à jour : ```bash kubectl get endpoints my-service ``` La sortie attendue montre l'IP du pod et le nouveau port : ```text NAME ENDPOINTS AGE my-service 10.244.1.5:8080 2m ``` ## Vérification et diagnostics Lorsqu'un problème réseau apparaît, commencez par des diagnostics qui ne changent pas l'état : inspectez les IP des pods, la résolution DNS et la connectivité. ### Vérifier les bases du réseau des pods Listez les pods avec leurs IP et nœuds : ```bash kubectl get pods -o wide ``` Exemple de sortie : ```text NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-748c8d9f5-8x7zr 1/1 Running 0 14m 10.244.1.5 worker-1 api-6f7b8c9d5-2p4tq 1/1 Running 0 14m 10.244.2.9 worker-2 ``` Si un pod est bloqué en `ContainerCreating`, vérifiez les événements : ```bash kubectl describe pod | tail -20 ``` Cherchez des messages comme `Failed to create pod sandbox` ou `network plugin is not ready`. Cela pointe souvent vers des problèmes de CNI. ### Tester la résolution DNS Les problèmes DNS sont courants. Vérifiez si le service DNS du cluster est opérationnel : ```bash kubectl get service -n kube-system kube-dns ``` Ou pour CoreDNS : ```bash kubectl get pods -n kube-system -l k8s-app=kube-dns ``` Sortie attendue : ```text NAME READY STATUS RESTARTS AGE coredns-5d78c9869d-7m6n2 1/1 Running 0 3d coredns-5d78c9869d-9x4k8 1/1 Running 0 3d ``` Si les pods tournent, testez la résolution depuis l'intérieur d'un pod. Créez un pod de débogage temporaire : ```bash kubectl run dns-test --image=busybox:1.28 --restart=Never -- sleep 3600 ``` Puis exécutez une commande dans celui-ci : ```bash kubectl exec -it dns-test -- nslookup kubernetes.default ``` La sortie attendue inclut l'IP du cluster pour le service Kubernetes : ```text Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes.default Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local ``` Si `nslookup` échoue, vérifiez les journaux CoreDNS : ```bash kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50 ``` ### Diagnostiquer les problèmes de port et de service Si un service ne route pas le trafic, vérifiez que le sélecteur correspond aux étiquettes des pods. Supposons que le service ait : ```yaml selector: app: web tier: frontend ``` Listez les pods avec ces étiquettes : ```bash kubectl get pods -l app=web,tier=frontend ``` Si aucun pod n'apparaît, le sélecteur est incorrect. Comparez avec les étiquettes réelles des pods : ```bash kubectl get pods --show-labels ``` Vérifiez également que le `targetPort` du service correspond au port du conteneur. Par exemple, si le conteneur écoute sur 8080 mais que le `targetPort` du service est 80, les connexions seront refusées. Vérifiez le port du conteneur dans la spécification du pod : ```bash kubectl get pod -o jsonpath='{.spec.containers[*].ports}' ``` Sortie attendue : ```text [{"containerPort":8080,"protocol":"TCP"}] ``` ## Modes de défaillance et récupération SSA introduit des modes de défaillance spécifiques liés à la propriété des champs et aux conflits. Savoir comment les récupérer est essentiel. ### Conflit lors de l'application Symptôme : `kubectl apply --server-side` renvoie une erreur de conflit indiquant les champs contestés. Exemple : ```text error: Apply failed with 2 conflicts: conflict with "ci-bot": .spec.ports, .spec.selector ``` Cela signifie qu'un autre gestionnaire SSA, `ci-bot`, possède ces champs. Pour procéder en toute sécurité, inspectez d'abord qui possède quoi : ```bash kubectl get service my-service -o yaml --show-managed-fields ``` Cherchez les noms de `manager` et les opérations. Si le conflit provient d'un système CI qui n'existe plus ou ne devrait pas posséder le champ, vous pouvez forcer la propriété : ```bash kubectl apply --server-side --field-manager=network-fix --force-conflicts -f service.yaml ``` Après avoir forcé, vérifiez que la propriété a changé : ```bash kubectl get service my-service -o yaml --show-managed-fields | grep -B 2 manager ``` Vous devriez voir `manager: network-fix` pour les champs que vous avez appliqués. ### Application partielle due à une validation échouée SSA valide l'objet entier avant de l'appliquer. Si un champ est invalide, toute l'application échoue, laissant l'objet inchangé. Pour récupérer, corrigez le champ invalide dans votre fichier local et réappliquez. Vous pouvez prévisualiser les erreurs de validation avec `dry-run` : ```bash kubectl apply --server-side --dry-run=server -f broken-service.yaml ``` Un message d'erreur apparaît : ```text The Service "my-service" is invalid: spec.ports[0].port: Invalid value: 0: must be between 1 and 65535, inclusive ``` Corrigez le port et appliquez à nouveau. ### Perte de propriété après force-conflicts Si vous forcez la propriété d'un champ, vous pouvez écraser un changement effectué par une autre équipe. La récupération nécessite d'identifier la valeur précédente. Si vous avez une sauvegarde (comme recommandé précédemment), vous pouvez la restaurer : ```bash kubectl apply --server-side --field-manager=network-fix -f service-backup-20240326-101112.yaml ``` Si aucune sauvegarde n'existe, vérifiez les journaux d'audit ou l'historique de l'objet dans un dépôt Git si GitOps est utilisé. Ensuite, réappliquez la configuration correcte. ## Pièges courants et comment les éviter ### 1. Ne pas spécifier de gestionnaire de champs Pourquoi cela arrive : Les utilisateurs exécutent `kubectl apply --server-side` sans `--field-manager`, donc Kubernetes utilise un nom de gestionnaire par défaut dérivé de l'utilisateur et de l'outil, tel que `kubectl`. Si plusieurs personnes appliquent le même objet, ils deviennent tous le même gestionnaire, ce qui entraîne des fusions silencieuses de propriété de champs et une résolution de conflit plus difficile. Comment l'éviter : Définissez toujours une valeur `--field-manager` explicite par équipe ou flux de travail. Par exemple, utilisez `--field-manager=platform-team` pour les changements de plateforme et `--field-manager=security-team` pour les mises à jour de politiques réseau. Récupération : Si vous avez déjà appliqué sans gestionnaire personnalisé, vous pouvez réappliquer avec un nouveau gestionnaire et `--force-conflicts` pour prendre possession des champs que vous avez l'intention de gérer. ### 2. Utiliser de manière interchangeable l'application côté client et côté serveur sur le même objet Pourquoi cela arrive : Les équipes migrent progressivement ; certains manifestes sont appliqués avec `kubectl apply` (côté client) et d'autres avec `--server-side`. Cela crée une propriété mixte et peut entraîner des suppressions de champs inattendues car l'application côté client efface les champs gérés côté serveur non présents dans le fichier local. Comment l'éviter : Standardisez sur SSA pour tous les objets de production. Si vous devez mélanger, sachez que l'application côté client utilise l'annotation `last-applied-configuration`, qui ne connaît pas la propriété des champs côté serveur. Testez dans un cluster de staging. Récupération : Si un champ a été supprimé, restaurez-le en réappliquant avec SSA et le bon gestionnaire de champs. ### 3. Ignorer les politiques réseau lors du diagnostic de connectivité Pourquoi cela arrive : Lorsque les pods ne peuvent pas se connecter, les développeurs supposent souvent un problème de DNS ou de configuration de service, négligeant une NetworkPolicy qui refuse le trafic. Comment l'éviter : Vérifiez toujours les NetworkPolicies dans le namespace : ```bash kubectl get networkpolicy -n ``` S'il en existe, décrivez-les pour voir quels pods elles sélectionnent et quel trafic elles autorisent : ```bash kubectl describe networkpolicy -n ``` Récupération : Si une NetworkPolicy bloque un trafic légitime, modifiez-la pour autoriser l'egress ou l'ingress requis. Appliquez le changement avec SSA et vérifiez la connectivité. ### 4. Modifier des ressources sans vérifier la propriété des champs SSA Pourquoi cela arrive : Un opérateur modifie un objet en direct avec `kubectl edit` ou le patche sans réaliser que SSA suit la propriété des champs. Plus tard, une application côté serveur échoue avec des conflits. Comment l'éviter : Avant de modifier, vérifiez les champs gérés : ```bash kubectl get -o yaml --show-managed-fields ``` Si un champ appartient à un autre gestionnaire, coordonnez-vous ou utilisez `--force-conflicts` seulement si nécessaire. Récupération : Si un conflit survient, inspectez la propriété, puis décidez de forcer ou d'abandonner le changement. Si vous forcez, documentez le changement et informez l'équipe de l'autre gestionnaire. ## Liste de contrôle des opérations Utilisez cette liste de contrôle avant et après avoir effectué des changements réseau dans un cluster géré par SSA. | Étape | Action | Commande / Détail | Responsable | Fréquence de revue | |-------|--------|------------------|-------------|--------------------| | 1 | Confirmer la version Kubernetes et le support SSA | `kubectl version --short` et `kubectl apply --server-side --dry-run=server -f test.yaml` | Responsable plateforme (ex. Priya Shah) | Trimestrielle ou après mise à niveau du cluster | | 2 | Sauvegarder tous les objets réseau affectés | `kubectl get svc,ep,ingress -o yaml > backup-$(date +%Y%m%d).yaml` | Ingénieur d'astreinte | Avant chaque changement | | 3 | Prévisualiser les changements avec diff | `kubectl diff -f updated.yaml` | Demandeur de changement | Chaque changement | | 4 | Appliquer avec un gestionnaire de champs explicite | `kubectl apply --server-side --field-manager=team-name -f updated.yaml` | Demandeur de changement | Chaque changement | | 5 | Vérifier le changement et les endpoints | `kubectl get service -o yaml` et `kubectl get endpoints ` | Ingénieur d'astreinte | Immédiatement après l'application | | 6 | Tester la résolution DNS si pertinent | `kubectl exec -it -- nslookup ` | Expert réseau (ex. Marcus Chen) | Après création de service ou changements DNS | | 7 | Vérifier les NetworkPolicies pour les blocages non intentionnels | `kubectl get networkpolicy -A` | Ingénieur sécurité (ex. Aisha Williams) | Hebdomadaire ou lors d'incidents de connectivité | | 8 | Documenter la procédure de retour en arrière | Conserver le fichier de sauvegarde et noter la commande : `kubectl apply --server-side --field-manager= -f backup.yaml` | Demandeur de changement | Chaque changement | Chaque responsable est une personne unique redevable ; elle peut déléguer l'exécution mais reste responsable de l'étape. ## Conclusion Server-Side Apply vous donne un contrôle précis sur la configuration Kubernetes, mais exige aussi une approche de dépannage disciplinée. En inventoriant votre environnement, en appliquant les changements en toute sécurité, en diagnostiquant avec des commandes en lecture seule et en planifiant les modes de défaillance courants, vous pouvez résoudre les problèmes réseau sans en créer de nouveaux. L'étape suivante consiste à choisir une vérification à faible risque dans ce guide, comme sauvegarder un service et vérifier ses champs gérés. Exécutez les commandes dans un namespace de développement, observez la sortie et comparez avec les résultats attendus. Explorez ensuite comment la propriété SSA affecte les flux de travail existants de votre équipe. Un flux de travail SSA fiable rend toujours les défaillances visibles, protège les données sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force une décision précipitée.