Helm ne crée pas de réseau ; il génère des manifestes Kubernetes qui définissent la façon dont vos services sont exposés et découverts. Lorsqu'une application déployée avec Helm n'est pas accessible, les causes se réduisent généralement à quelques catégories : résolution DNS, ports et endpoints, routage et NetworkPolicies, configuration Ingress, attribution d'un load balancer cloud, ou pare-feu et proxys hôtes.

Ce guide propose un parcours pratique, étape par étape, pour diagnostiquer et corriger les problèmes réseau liés à Helm sans devinette. Vous ferez l'inventaire de votre environnement, rendrez et inspecterez ce qu'Helm va appliquer, lancerez des tests de connectivité sûrs depuis l'intérieur du cluster, et utiliserez des procédures claires de récupération et de rollback.

Les exemples construits dans cet article utilisent des noms hypothétiques comme myapp , ns-demo et example.local pour illustrer les commandes et les sorties attendues.

## Inventaire des versions et de l'environnement

Commencez par des faits fiables. Enregistrez les versions, les contextes et les détails du release afin que chaque test et correctif soit traçable.

Prérequis

- Accès au cluster Kubernetes et à l'espace de noms où s'exécute le release Helm

- kubectl et helm installés sur votre poste de travail

- RBAC autorisant la lecture de l'espace de noms cible et de kube-system pour les vérifications DNS

Commandes d'inventaire (lecture seule)

# Versions
helm version --short
kubectl version --short

# Contexte et espace de noms actuels
kubectl config current-context
kubectl get ns

# Releases Helm dans votre espace de noms cible
NAMESPACE=ns-demo
helm list -n "$NAMESPACE"

# Capture des valeurs et des manifestes rendus pour un release donné
RELEASE=myapp
helm get values "$RELEASE" -n "$NAMESPACE" --all > values.$RELEASE.yaml
helm get manifest "$RELEASE" -n "$NAMESPACE" > manifest.$RELEASE.yaml

# Alternative : rendre localement sans appliquer
CHART_PATH=./charts/myapp
helm template "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml > rendered.$RELEASE.yaml 
 Résultats attendus

- Vous connaissez le nom exact du release Helm et l'espace de noms.

- Vous disposez de values.$RELEASE.yaml et rendered.$RELEASE.yaml pour inspecter les définitions de Service, Ingress et NetworkPolicy.

Si l'une de ces étapes échoue, corrigez les problèmes d'accès ou de chemin avant de continuer. Un release ou un espace de noms manquant indique que vous ciblez peut-être le mauvais environnement.

## Parcours de configuration sécurisé

Minimisez les risques pendant que vous sondez l'état du réseau.

Portée et isolation

- Travaillez dans l'espace de noms spécifique. Passez toujours -n "$NAMESPACE" à helm et kubectl.

- Privilégiez d'abord les commandes kubectl get/describe et helm get/template en lecture seule.

- Pour les tests intra-cluster, créez des pods éphémères que vous supprimerez une fois terminés. Ne modifiez pas les pods ou services de l'application avant d'avoir un constat clair.

Garde-fous

- Ne modifiez pas les paramètres DNS ou CNI au niveau du cluster pendant le tri initial.

- Utilisez helm upgrade avec --wait et un --timeout raisonnable pour des changements contrôlés.

- Gardez le rollback disponible : utilisez helm history et helm rollback .

# Aperçu d'un changement prévu sans l'appliquer
helm template "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml > /tmp/proposed.yaml

# Appliquer un changement avec sécurité
helm upgrade "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml --wait --timeout 5m

# Revenir en arrière si nécessaire
helm history "$RELEASE" -n "$NAMESPACE"
# Choisir une REV connue bonne
helm rollback "$RELEASE" REV -n "$NAMESPACE" --wait --timeout 5m 

## Vérification et diagnostics

 Procédez du général au spécifique. Arrêtez-vous à la première couche qui échoue et corrigez-la avant de continuer.

Tableau de correspondance symptôme → premier contrôle

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Symptôme</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Premier contrôle</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Cause probable</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Un pod ne résout pas un nom de service</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Requête DNS depuis un pod de test intra-cluster</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Problème CoreDNS ou mauvais nom/namespace de service</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Le service n&#39;a pas d&#39;endpoints</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Sélecteurs vs étiquettes des pods</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Désaccord d&#39;étiquettes ou pods pas Ready</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Port ouvert mais HTTP échoue</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mismatch port/targetPort ou échecs de readiness probe</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mapping values.yaml incorrect ou application pas prête</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Hôte Ingress inaccessible</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Statut et règles Ingress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mauvais hôte, TLS ou classe de contrôleur</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">EXTERNAL-IP en Pending</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Événements du service LoadBalancer</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Provisionnement LB cloud ou quota</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Fonctionne dans le cluster, pas à l&#39;extérieur</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Pare-feu nœud ou groupe de sécurité cloud</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Blocage sortie/entrée au niveau hôte ou réseau</td></tr></tbody>
</table>
</div>
Note : les éléments du tableau sont des exemples construits.

## 1) Connectivité du cluster et portée de l'espace de noms

kubectl cluster-info
kubectl get ns | grep -E "(^NAME|$NAMESPACE)"\nhelm status "$RELEASE" -n "$NAMESPACE" 
 Résultats attendus

- cluster-info retourne les URLs du control plane.

- helm status affiche le release avec la liste des ressources.

Si helm status échoue, confirmez le release et l'espace de noms. Si le release se trouve dans un autre espace de noms, changez ou ajustez NAMESPACE .

## 2) Inspecter les Services, Endpoints et Ingress rendus

Rendez et comparez ce qu'Helm a prévu avec ce qui tourne.

# Ressources en cours
kubectl get svc,ep,ingress -n "$NAMESPACE"

# Description détaillée pour un service précis
SVC=myapp-svc
kubectl describe svc "$SVC" -n "$NAMESPACE"

# Les endpoints doivent lister les IP des pods et les ports
kubectl get endpoints "$SVC" -n "$NAMESPACE" -o wide

# Afficher les étiquettes et la readiness des pods
kubectl get pods -n "$NAMESPACE" -o wide --show-labels 
 Résultats attendus

- Le sélecteur du Service correspond aux étiquettes des pods (ex. app=myapp ).

- Les endpoints montrent au moins une IP de pod Ready et le bon port.

Constat fréquent : les endpoints sont vides. Corrigez le sélecteur ou les étiquettes des pods dans values.yaml et redéployez, ou faites un rollback vers une révision connue.

## 3) DNS : découverte de service à l'intérieur du cluster

Validez le DNS depuis l'intérieur du cluster. Utilisez un pod BusyBox éphémère ou équivalent. Supprimez le pod ensuite.

# Créer un pod éphémère pour tests DNS et connectivité
TEST_NS="$NAMESPACE"
kubectl run net-test -n "$TEST_NS" --image=busybox:1.35 --restart=Never --command -- sh -c "sleep 3600"

# Attendre qu'il soit Running
kubectl wait --for=condition=Ready pod/net-test -n "$TEST_NS" --timeout=60s

# Requêtes DNS
kubectl exec -n "$TEST_NS" net-test -- nslookup kubernetes.default.svc.cluster.local || true
kubectl exec -n "$TEST_NS" net-test -- nslookup myapp-svc.$TEST_NS.svc.cluster.local || true

# Nettoyer plus tard avec : kubectl delete pod/net-test -n "$TEST_NS" 
 Résultats attendus

- kubernetes.default.svc.cluster.local résout vers l'IP cluster de l'API server.

- myapp-svc.$TEST_NS.svc.cluster.local résout vers l'IP cluster du Service.

Si le DNS échoue

- Vérifiez CoreDNS :

kubectl -n kube-system get deploy,po -l k8s-app=kube-dns || true
kubectl -n kube-system get deploy,po -l k8s-app=coredns || true
kubectl -n kube-system logs deploy/coredns --tail=200 || true
kubectl -n kube-system get svc kube-dns || true 

- Inspectez le nom du service et l'espace de noms. Les fautes de frappe sont fréquentes. Assurez-vous que le FQDN correspond à serviceName.namespace.svc.cluster.local .

## 4) Ports et targetPorts : confirmer le câblage

 Vérifiez que le port du Service et le targetPort correspondent au port du conteneur exposé par le pod. Comparez le YAML rendu par Helm aux objets en cours.

# Depuis le YAML rendu par Helm (rechercher le bloc Service)
grep -n "kind: Service" rendered.$RELEASE.yaml | head -n 1
# Puis ouvrez autour de cette section pour lire ports et selectors

# Vérification live des ports
kubectl get svc "$SVC" -n "$NAMESPACE" -o yaml | grep -A5 "ports:"

# Ports des conteneurs dans les pods
POD=$(kubectl get pods -n "$NAMESPACE" -l app=myapp -o jsonpath='{.items[0].metadata.name}')
kubectl get pod "$POD" -n "$NAMESPACE" -o jsonpath='{.spec.containers[*].ports}' ; echo 
 Résultats attendus

- Pour du HTTP sur 8080, Service.spec.ports[0].port pourrait être 80, targetPort 8080, et le conteneur avoir containerPort 8080 .

Si targetPort ne correspond pas au containerPort sur lequel l'application écoute réellement, mettez à jour values.yaml et redéployez, ou faites un rollback.

## 5) Tests de connectivité depuis l'intérieur du cluster

Utilisez des outils simples pour vérifier la reachability TCP et un HTTP basique depuis le pod net-test créé plus tôt.

# Test TCP vers le nom de service et le port
kubectl exec -n "$TEST_NS" net-test -- sh -c "nc -vz myapp-svc.$TEST_NS.svc.cluster.local 8080 || true"

# Test HTTP (si l'application parle HTTP)
kubectl exec -n "$TEST_NS" net-test -- sh -c "wget -S -O - http://myapp-svc.$TEST_NS.svc.cluster.local:8080/health || true" 
 Résultats attendus

- nc affiche succeeded (ouvert) et wget retourne un 200 ou le statut attendu pour /health .

Si TCP échoue mais DNS fonctionne, revoyez Endpoints et NetworkPolicies. Si HTTP échoue alors que TCP s'ouvre, vérifiez les readiness probes et les logs de l'application.

## 6) NetworkPolicies : autoriser le trafic explicitement

Si votre cluster utilise des NetworkPolicies, les services peuvent être accessibles seulement depuis certains pods/espaces de noms. Listez les politiques et cherchez les interdictions.

kubectl get networkpolicy -A
kubectl describe networkpolicy -n "$NAMESPACE" # examiner les politiques dans l'espace de noms de l'app 
 Résultats attendus

- Soit aucune politique n'existe, soit les politiques existantes autorisent le trafic depuis les sources attendues vers vos étiquettes de pods et ports.

Approche de correction

- Ajoutez ou ajustez une politique d'autorisation pour le sélecteur de l'app sur les ports requis. Appliquez via Helm si les politiques font partie du chart. Validez avec les mêmes commandes net-test.

## 7) Ingress et exposition externe

Si vous exposez l'app via Ingress, confirmez les règles, la classe et le statut.

ING=myapp-ing
kubectl get ingress "$ING" -n "$NAMESPACE" -o yaml | grep -E "host:|ingressClassName|tls:|service:" -n
kubectl describe ingress "$ING" -n "$NAMESPACE" 
 Résultats attendus

- L'hôte correspond à votre entrée DNS (ex. app.example.local ).

- Le serviceName et le servicePort s'alignent avec votre Service.

- L'Ingress possède une adresse dans status.loadBalancer.ingress ou votre contrôleur annonce un VIP accessible.

Idées de dépannage

- Si l'hôte est incorrect, corrigez values.yaml et upgrade.

- Si le statut n'a pas d'adresse, vérifiez le déploiement du contrôleur Ingress et son service.

- Pour les problèmes TLS, vérifiez le nom du secret et la validité du certificat.

## 8) Services LoadBalancer et NodePort

Pour un Service de type LoadBalancer, assurez-vous que l'IP externe est provisionnée et ouverte.

kubectl get svc "$SVC" -n "$NAMESPACE" -o wide
kubectl describe svc "$SVC" -n "$NAMESPACE" | sed -n '/Events/,$p' 
 Résultats attendus

- EXTERNAL-IP est renseignée (pas Pending) et les ports correspondent aux attentes.

Si EXTERNAL-IP reste Pending

- Revoyez l'intégration du fournisseur cloud et les quotas (les événements du cluster peuvent indiquer la raison).

- En voie temporaire, passez en NodePort pour tests internes et accédez via nodeIP:nodePort (uniquement dans des environnements contrôlés).

## 9) Pare-feu hôtes et proxys

Quand ça fonctionne intra-cluster mais pas depuis l'extérieur, inspectez les pare-feu hôtes et les proxys.

# Vues rapides du pare-feu Linux (exécuter sur les nœuds cibles si accès)
sudo iptables -S | head -n 50 || true
sudo nft list ruleset | head -n 80 || true
sudo ufw status verbose || true

# Proxys poste de travail ou jump-host
env | grep -i _proxy || true 
 Actions

- Autorisez les ports entrants requis sur les nœuds ou via le groupe de sécurité cloud.

- Configurez NO_PROXY pour inclure les sous-réseaux du cluster et .svc,.cluster.local si votre client Helm ou vos outils ont besoin d'un accès direct :

export NO_PROXY="127.0.0.1,localhost,.svc,.cluster.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" 

## Correspondance des valeurs Helm aux champs réseau

 Si votre chart est piloté par des valeurs, confirmez comment les clés values.yaml mappent vers Service et Ingress. Lisez les templates et les valeurs par défaut du chart.

Exemple de correspondance construit

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Clé values Helm</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Ressource affectée</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Champ typique</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">service.type</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Service</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">spec.type</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">service.port</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Service</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">spec.ports[].port</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">service.targetPort</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Service</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">spec.ports[].targetPort</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">service.annotations</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Service</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">metadata.annotations</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ingress.enabled</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ingress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">N/A (présence de la ressource)</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ingress.className</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ingress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">spec.ingressClassName</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ingress.hosts[0].host</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ingress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">spec.rules[].host</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ingress.hosts[0].paths[0].service.port</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ingress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">spec.rules[].http.paths[].backend.service.port</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">networkPolicy.enabled</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">NetworkPolicy</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">N/A (présence de la ressource)</td></tr></tbody>
</table>
</div>
Utilisez helm template pour rendre et confirmer ces champs avant d'appliquer des changements.

## Modes de défaillance et récupération

Voici les modes de défaillance courants avec correctifs précis, vérifications attendues et guidance de rollback. Tous les exemples sont construits.

- La résolution DNS échoue à l'intérieur du cluster

- Symptôme : nslookup myapp-svc.ns-demo.svc.cluster.local échoue.

- Cause probable : CoreDNS non opérationnel, mauvais nom/namespace de service.

- Correctif :

- Vérifiez que le déploiement CoreDNS est sain : kubectl -n kube-system get deploy coredns .

- Corrigez les références au FQDN du service dans les probes ou autres charts.

- Vérification : relancez nslookup depuis net-test ; attendez un enregistrement A.

- Rollback : si vous avez modifié le ConfigMap CoreDNS et cassé la résolution, restaurez ce ConfigMap depuis une sauvegarde ou appliquez la version précédente connue bonne, puis redémarrez les pods CoreDNS.

- Le service n'a pas d'endpoints

- Symptôme : kubectl get endpoints myapp-svc affiche <none> .

- Cause probable : le sélecteur du Service ne correspond pas aux étiquettes des pods ; pods pas Ready.

- Correctif :

- Comparez Service.selector à kubectl get pods --show-labels .

- Mettez à jour les étiquettes ou sélecteurs dans values.yaml , puis helm upgrade .

- Vérification : les endpoints listent les IP des pods avec les bons ports.

- Rollback : helm rollback vers la dernière révision avec sélecteurs correspondants.

- Mismatch port/targetPort

- Symptôme : TCP connecte mais la requête échoue ou timeout ; les logs montrent l'app écoutant sur un autre port.

- Correctif :

- Alignez service.targetPort avec le containerPort ou le port d'écoute de l'app dans values.yaml .

- Si vous utilisez des ports nommés, assurez-vous que le conteneur et le Service référencent le même nom.

- Vérification : wget http://service:port/health retourne le statut attendu.

- Rollback : helm rollback vers la révision avant le changement de port si une perturbation s'est produite.

- NetworkPolicy bloque le trafic

- Symptôme : fonctionne depuis certains pods mais pas d'autres ; net-test échoue dans certains namespaces.

- Correctif :

- Ajoutez une politique d'autorisation pour le sélecteur de l'app et les ports requis depuis les namespaces appelants.

- Appliquez via Helm si le chart possède les politiques.

- Vérification : répétez les tests TCP/HTTP net-test depuis les namespaces autorisés et non autorisés.

- Rollback : annulez le dernier changement de politique via helm rollback ou kubectl apply du manifeste précédent.

- Mauvaise configuration de l'hôte Ingress

- Symptôme : curl vers https://app.example.local échoue avec 404 ou erreur TLS.

- Correctif :

- Assurez-vous que ingress.hosts[].host correspond à l'enregistrement DNS externe.

- Définissez ingress.className pour qu'il corresponde à votre contrôleur.

- Vérifiez les noms de secrets TLS.

- Vérification : kubectl describe ingress montre règles et adresse correctes ; curl retourne la réponse de l'app.

- Rollback : helm rollback vers la dernière configuration Ingress connue bonne.

- EXTERNAL-IP en Pending sur un service LoadBalancer

- Symptôme : EXTERNAL-IP reste Pending pendant des minutes ; les événements mentionnent le provisionnement.

- Correctif :

- Vérifiez quotas et permissions du fournisseur cloud ; ajustez les annotations si requis par votre environnement.

- Passez temporairement en NodePort pour tests internes si sûr.

- Vérification : kubectl get svc affiche une EXTERNAL-IP renseignée ou un NodePort accessible.

- Rollback : si un changement d'annotations a causé l'échec, supprimez ou revenez aux annotations précédentes et redéployez.

- L'environnement proxy interfère avec Helm ou les tests

- Symptôme : helm repo update ou tests de connectivité se comportent de façon incohérente.

- Correctif :

- Définissez NO_PROXY pour inclure les domaines intra-cluster et CIDRs ; désactivez HTTP(S)_PROXY pour les adresses intra-cluster.

- Vérification : relancez helm repo update et tests intra-cluster.

- Rollback : restaurez les paramètres proxy précédents si nécessaire et documentez les exclusions.

## Flux pratique de rollback et récupération

Utilisez l'historique Helm pour choisir une base stable, puis avancez avec de petits changements testables.

# Inspecter les révisions et dates
helm history "$RELEASE" -n "$NAMESPACE"

# Revenir à une version fonctionnelle précise
helm rollback "$RELEASE" REV -n "$NAMESPACE" --wait --timeout 5m

# Réappliquer un fichier values corrigé
helm upgrade "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml --wait --timeout 5m 
 Résultats attendus

- Le rollback se termine sans erreur, et Services/Ingress reviennent à un comportement connu bon.

- Après application des corrections, les vérifications passent dans l'ordre décrit plus haut.

## Vérification : passe de sanity end-to-end

Après correctifs, relancez les vérifications minimales end-to-end :

- Rendu vs en cours

- helm get manifest vs kubectl get svc/ing/ep montrent ports, sélecteurs et hôtes cohérents.

- DNS

- nslookup service.namespace.svc.cluster.local résout à l'intérieur du cluster.

- TCP et HTTP

- nc -vz service port réussit ; wget http://service:port/health retourne le code attendu.

- Ingress

- kubectl describe ingress affiche hôte et adresse corrects ; curl avec l'hôte retourne l'app.

- Accès externe

- Si LoadBalancer, EXTERNAL-IP répond sur le port attendu.

## Check-list opérationnelle

Utilisez cette check-list concise pour chaque incident réseau Helm.

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Étape</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Commande ou action</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Signal attendu</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">1. Inventaire</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">helm version; kubectl version; helm list -n ns</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Versions enregistrées ; release localisé</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">2. Values &amp; render</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">helm get values; helm template</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Champs Service/Ingress visibles</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">3. État live</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get svc,ep,ing -n ns</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ressources présentes ; endpoints non vides</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">4. DNS intra-cluster</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">nslookup service.ns.svc.cluster.local</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Enregistrement A retourné</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">5. Ports</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl describe svc; comparer targetPort/containerPort</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ports alignés</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">6. Test TCP/HTTP</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">nc -vz; wget http://service:port/health</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Connexion et code 200/attendu</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">7. Politiques</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get/describe networkpolicy</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Autorisations correspondent au trafic</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">8. Ingress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl describe ingress; curl hôte</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Règles et TLS corrects</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">9. IP externe</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get svc -o wide</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">EXTERNAL-IP assignée</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">10. Pare-feu/proxy</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">iptables/nft/ufw; NO_PROXY défini</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Chemins ouverts ; pas d&#39;interférence proxy</td></tr></tbody>
</table>
</div>

## Conclusion

Le dépannage réseau Helm consiste à valider les ressources Kubernetes qu'Helm rend et leur interaction avec le DNS, les ports et le routage du cluster. En :

- Inventoriant versions, espaces de noms, noms de release et manifestes rendus,

- Testant d'abord le DNS et la connectivité depuis l'intérieur du cluster,

- Vérifiant les sélecteurs de service, endpoints et mappings de ports,

- Contrôlant NetworkPolicies, règles Ingress et attribution d'IP externe,

- Et appliquant les changements avec helm upgrade --wait tout en gardant helm rollback prêt,

vous pouvez isoler rapidement les causes racines et récupérer en toute sécurité. Commencez par un test étroit et mesurable — par exemple, résoudre le FQDN du service et appeler un endpoint /health — avant d'élargir la portée. Avec ces pratiques, les déploiements pilotés par Helm restent observables, débogables et résilients face aux surprises réseau.