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 :
kubectl version --short
La sortie attendue ressemble à :
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 :
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é :
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é :
kubectl get pods -n kube-system | grep -E 'calico|flannel|weave|cilium|aws-node|azure-cni'
Par exemple, un cluster basé sur Calico affiche :
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 :
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 :
kubectl get services,endpoints,ingresses -o wide
Notez la colonne MANAGED FIELDS si présente ; avec kubectl get, vous pouvez la demander explicitement :
kubectl get service my-service -o yaml | grep -A 5 managedFields
Une entrée typique montre le gestionnaire et l'opération :
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 :
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 :
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 :
spec:
ports:
- name: http
port: 80
targetPort: 80
Modifiez uniquement le champ targetPort :
spec:
ports:
- name: http
port: 80
targetPort: 8080
Appliquez avec Server-Side Apply et spécifiez explicitement le gestionnaire de champs :
kubectl apply --server-side --field-manager=network-fix -f updated-service.yaml
Sortie attendue :
service/my-service serverside-applied
Si un autre gestionnaire possède le champ targetPort, vous verrez un conflit :
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 :
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 :
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 :
kubectl get endpoints my-service
La sortie attendue montre l'IP du pod et le nouveau port :
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 :
kubectl get pods -o wide
Exemple de sortie :
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 <none> <none>
api-6f7b8c9d5-2p4tq 1/1 Running 0 14m 10.244.2.9 worker-2 <none> <none>
Si un pod est bloqué en ContainerCreating, vérifiez les événements :
kubectl describe pod <pod-name> | 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 :
kubectl get service -n kube-system kube-dns
Ou pour CoreDNS :
kubectl get pods -n kube-system -l k8s-app=kube-dns
Sortie attendue :
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 :
kubectl run dns-test --image=busybox:1.28 --restart=Never -- sleep 3600
Puis exécutez une commande dans celui-ci :
kubectl exec -it dns-test -- nslookup kubernetes.default
La sortie attendue inclut l'IP du cluster pour le service Kubernetes :
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 :
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 :
selector:
app: web
tier: frontend
Listez les pods avec ces étiquettes :
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 :
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 :
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].ports}'
Sortie attendue :
[{"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 :
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 :
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é :
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é :
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 :
kubectl apply --server-side --dry-run=server -f broken-service.yaml
Un message d'erreur apparaît :
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 :
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 :
kubectl get networkpolicy -n <namespace>
S'il en existe, décrivez-les pour voir quels pods elles sélectionnent et quel trafic elles autorisent :
kubectl describe networkpolicy <policy-name> -n <namespace>
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 :
kubectl get <resource> <name> -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 <name> -o yaml et kubectl get endpoints <name> | Ingénieur d'astreinte | Immédiatement après l'application |
| 6 | Tester la résolution DNS si pertinent | kubectl exec -it <debug-pod> -- nslookup <service-name> | 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=<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.