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
kubectlethelminstallés sur votre poste de travail- RBAC autorisant la lecture de l'espace de noms cible et de
kube-systempour 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.yamletrendered.$RELEASE.yamlpour 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/describeethelm get/templateen 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 upgradeavec--waitet un--timeoutraisonnable pour des changements contrôlés. - Gardez le rollback disponible : utilisez
helm historyethelm 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
| Symptôme | Premier contrôle | Cause probable |
|---|---|---|
| Un pod ne résout pas un nom de service | Requête DNS depuis un pod de test intra-cluster | Problème CoreDNS ou mauvais nom/namespace de service |
| Le service n'a pas d'endpoints | Sélecteurs vs étiquettes des pods | Désaccord d'étiquettes ou pods pas Ready |
| Port ouvert mais HTTP échoue | Mismatch port/targetPort ou échecs de readiness probe | Mapping values.yaml incorrect ou application pas prête |
| Hôte Ingress inaccessible | Statut et règles Ingress | Mauvais hôte, TLS ou classe de contrôleur |
| EXTERNAL-IP en Pending | Événements du service LoadBalancer | Provisionnement LB cloud ou quota |
| Fonctionne dans le cluster, pas à l'extérieur | Pare-feu nœud ou groupe de sécurité cloud | Blocage sortie/entrée au niveau hôte ou réseau |
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-inforetourne les URLs du control plane.helm statusaffiche 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.localrésout vers l'IP cluster de l'API server.myapp-svc.$TEST_NS.svc.cluster.localré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].portpourrait être 80,targetPort8080, et le conteneur avoircontainerPort 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
ncaffiche succeeded (ouvert) etwgetretourne 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
serviceNameet leservicePorts'alignent avec votre Service. - L'Ingress possède une adresse dans
status.loadBalancer.ingressou votre contrôleur annonce un VIP accessible.
Idées de dépannage
- Si l'hôte est incorrect, corrigez
values.yamlet 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-IPest 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_PROXYpour inclure les sous-réseaux du cluster et.svc,.cluster.localsi 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
| Clé values Helm | Ressource affectée | Champ typique |
|---|---|---|
service.type | Service | spec.type |
service.port | Service | spec.ports[].port |
service.targetPort | Service | spec.ports[].targetPort |
service.annotations | Service | metadata.annotations |
ingress.enabled | Ingress | N/A (présence de la ressource) |
ingress.className | Ingress | spec.ingressClassName |
ingress.hosts[0].host | Ingress | spec.rules[].host |
ingress.hosts[0].paths[0].service.port | Ingress | spec.rules[].http.paths[].backend.service.port |
networkPolicy.enabled | NetworkPolicy | N/A (présence de la ressource) |
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-svcaffiche<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, puishelm upgrade. - Vérification : les endpoints listent les IP des pods avec les bons ports.
- Rollback :
helm rollbackvers 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.targetPortavec lecontainerPortou le port d'écoute de l'app dansvalues.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/healthretourne le statut attendu. - Rollback :
helm rollbackvers 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 rollbackoukubectl applydu manifeste précédent.
- Mauvaise configuration de l'hôte Ingress
- Symptôme :
curlvershttps://app.example.localéchoue avec 404 ou erreur TLS. - Correctif :
- Assurez-vous que
ingress.hosts[].hostcorrespond à l'enregistrement DNS externe. - Définissez
ingress.classNamepour qu'il corresponde à votre contrôleur. - Vérifiez les noms de secrets TLS.
- Vérification :
kubectl describe ingressmontre règles et adresse correctes ;curlretourne la réponse de l'app. - Rollback :
helm rollbackvers la dernière configuration Ingress connue bonne.
- EXTERNAL-IP en Pending sur un service LoadBalancer
- Symptôme :
EXTERNAL-IPreste 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 svcaffiche uneEXTERNAL-IPrenseigné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 updateou tests de connectivité se comportent de façon incohérente. - Correctif :
- Définissez
NO_PROXYpour inclure les domaines intra-cluster et CIDRs ; désactivezHTTP(S)_PROXYpour les adresses intra-cluster. - Vérification : relancez
helm repo updateet 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 manifestvskubectl get svc/ing/epmontrent ports, sélecteurs et hôtes cohérents.
- DNS
nslookup service.namespace.svc.cluster.localrésout à l'intérieur du cluster.
- TCP et HTTP
nc -vz service portréussit ;wget http://service:port/healthretourne le code attendu.
- Ingress
kubectl describe ingressaffiche hôte et adresse corrects ;curlavec l'hôte retourne l'app.
- Accès externe
- Si LoadBalancer,
EXTERNAL-IPrépond sur le port attendu.
Check-list opérationnelle
Utilisez cette check-list concise pour chaque incident réseau Helm.
| Étape | Commande ou action | Signal attendu |
|---|---|---|
| 1. Inventaire | helm version; kubectl version; helm list -n ns | Versions enregistrées ; release localisé |
| 2. Values & render | helm get values; helm template | Champs Service/Ingress visibles |
| 3. État live | kubectl get svc,ep,ing -n ns | Ressources présentes ; endpoints non vides |
| 4. DNS intra-cluster | nslookup service.ns.svc.cluster.local | Enregistrement A retourné |
| 5. Ports | kubectl describe svc; comparer targetPort/containerPort | Ports alignés |
| 6. Test TCP/HTTP | nc -vz; wget http://service:port/health | Connexion et code 200/attendu |
| 7. Politiques | kubectl get/describe networkpolicy | Autorisations correspondent au trafic |
| 8. Ingress | kubectl describe ingress; curl hôte | Règles et TLS corrects |
| 9. IP externe | kubectl get svc -o wide | EXTERNAL-IP assignée |
| 10. Pare-feu/proxy | iptables/nft/ufw; NO_PROXY défini | Chemins ouverts ; pas d'interférence proxy |
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 --waittout en gardanthelm rollbackprê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.