Intro
Cette version française explique Helm networking troubleshooting with practical examples avec le même objectif pratique que l article source : aider le lecteur à comprendre le contexte, les décisions à prendre et les points à vérifier avant de passer à l action.
Helm ne crée pas de réseau ; il rend des manifests Kubernetes qui définissent comment vos services sont exposés et découverts. Si une application déployée avec Helm n'est pas accessible, les causes se situent généralement dans quelques catégories : résolution DNS, ports et Endpoints, routage et NetworkPolicies, configuration d'Ingress, attribution d'un LoadBalancer par le cloud, ou encore pare-feu/proxys hôtes. Ce guide propose un chemin pratique et pas à pas pour du Helm network troubleshooting sans tâtonner : inventorier l'environnement, rendre et inspecter ce que Helm va appliquer, exécuter des tests sûrs depuis le cluster, puis corriger avec des procédures claires de récupération et de rollback.
Les exemples utilisent des noms construits comme myapp, ns-demo et example.local pour illustrer commandes et sorties attendues.
Inventaire des versions et de l'environnement
Commencez par des faits vérifiables. Notez versions, contextes et détails de release pour une traçabilité complète.
Prérequis
- Accès au cluster Kubernetes et à l'espace de noms de la release Helm
- kubectl et helm installés
- Droits RBAC en lecture sur l'espace de noms cible et kube-system pour les vérifications DNS
Commandes d'inventaire (lecture seule)
# Versions
helm version --short
kubectl version --short
# Contexte et namespaces
kubectl config current-context
kubectl get ns
# Releases Helm dans le namespace cible
NAMESPACE=ns-demo
helm list -n "$NAMESPACE"
# Capturer les valeurs et manifests rendus
RELEASE=myapp
helm get values "$RELEASE" -n "$NAMESPACE" --all > values.$RELEASE.yaml
helm get manifest "$RELEASE" -n "$NAMESPACE" > manifest.$RELEASE.yaml
# Rendu local 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 exactement le nom de release Helm et le namespace.
- Vous disposez de values.$RELEASE.yaml et rendered.$RELEASE.yaml pour inspecter Service, Ingress et NetworkPolicy.
Si une étape échoue, corrigez l'accès ou le chemin avant de continuer. Une release ou un namespace manquant signifie probablement une mauvaise cible.
Chemin de configuration sûr
Minimisez les risques pendant vos investigations.
Portée et isolation
- Travaillez dans le namespace spécifique. Passez toujours -n "$NAMESPACE" à helm et kubectl.
- Préférez kubectl get/describe et helm get/template en lecture seule d'abord.
- Pour les tests en cluster, créez des pods éphémères à supprimer ensuite. N'altérez pas les pods ou services applicatifs tant que vous n'avez pas de constat clair.
Garde-fous
- Ne changez pas le DNS ou la CNI du cluster en phase de triage initial.
- Utilisez helm upgrade avec --wait et un --timeout raisonnable.
- Gardez le rollback à portée : helm history et helm rollback.
# Prévisualiser un changement
helm template "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml > /tmp/proposed.yaml
# Appliquer avec sécurité
helm upgrade "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml --wait --timeout 5m
# Revenir en arrière si besoin
helm history "$RELEASE" -n "$NAMESPACE"
# Choisir un REV connu
helm rollback "$RELEASE" REV -n "$NAMESPACE" --wait --timeout 5m
Vérifications et diagnostic
Progressez du général au spécifique. Arrêtez-vous à la première couche défaillante et corrigez avant d'avancer.
Carte rapide symptôme → premier contrôle (exemples)
| Symptôme | Premier contrôle | Cause probable |
|---|---|---|
| Un pod ne résout pas un nom de service | Lookup DNS depuis un pod de test | CoreDNS en défaut ou nom/namespace erroné |
| Service sans endpoints | Sélecteurs vs labels de pod | Labels incohérents ou pods non Ready |
| Port ouvert mais HTTP en échec | port/targetPort ou readiness | Mauvais mapping values.yaml ou app non prête |
| Hôte Ingress injoignable | Status et règles Ingress | Hôte/TLS/classe de contrôleur erronés |
| EXTERNAL-IP Pending | Événements du Service LB | Provisionnement cloud ou quota |
| OK en cluster, KO depuis l'externe | Pare-feu nœud / groupe sécu | Flux bloqué au niveau hôte ou réseau |
1) Connectivité du cluster et périmètre du namespace
kubectl cluster-info
kubectl get ns | grep -E "(^NAME|$NAMESPACE)"
helm status "$RELEASE" -n "$NAMESPACE"
Résultats attendus
- cluster-info renvoie les URLs du plan de contrôle.
- helm status liste les ressources de la release.
Si helm status échoue, confirmez la release et le namespace.
2) Inspecter Services, Endpoints et Ingress
Rendez et comparez l'intention (Helm) avec l'état courant.
# Ressources en exécution
kubectl get svc, ep, ingress -n "$NAMESPACE"
# Détails d'un service
SVC=myapp-svc
kubectl describe svc "$SVC" -n "$NAMESPACE"
# Les endpoints doivent lister des IP de pods et ports
kubectl get endpoints "$SVC" -n "$NAMESPACE" -o wide
# Labels de pods et readiness
kubectl get pods -n "$NAMESPACE" -o wide --show-labels
Résultats attendus
- Le selector du Service correspond aux labels des pods (ex. app=myapp).
- Les Endpoints montrent au moins un pod Ready avec le bon port.
Si Endpoints est vide, corrigez selector ou labels dans values.yaml puis déployez, ou rollback.
3) DNS : découverte de service en cluster
Vérifiez le DNS depuis le cluster via un pod éphémère (BusyBox). Supprimez-le ensuite.
TEST_NS="$NAMESPACE"
kubectl run net-test -n "$TEST_NS" --image=busybox:1.35 --restart=Never --command -- sh -c "sleep 3600"
kubectl wait --for=condition=Ready pod/net-test -n "$TEST_NS" --timeout=60s
# Lookups 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
Résultats attendus
- kubernetes.default.svc.cluster.local se résout vers l'IP cluster de l'API.
- myapp-svc.$TEST_NS.svc.cluster.local se résout vers l'IP cluster du Service.
Si le DNS échoue, contrôlez 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
Assurez-vous aussi que le FQDN correspond à serviceName.namespace.svc.cluster.local.
4) Ports et targetPort : vérifier le câblage
Confirmez l'alignement entre Service.port, Service.targetPort et containerPort.
# Depuis le YAML rendu Helm
grep -n "kind: Service" -n rendered.$RELEASE.yaml -n | head -n 1
# Ports en live
kubectl get svc "$SVC" -n "$NAMESPACE" -o yaml | grep -A5 "ports:"
# Ports des conteneurs
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
- Exemple : HTTP en 8080 → Service.port=80, targetPort=8080, containerPort=8080.
Si targetPort ne correspond pas, mettez à jour values.yaml et redéployez, ou rollback.
5) Tests de connectivité en cluster
Vérifiez la connectivité TCP et un HTTP basique depuis net-test.
# Test TCP
kubectl exec -n "$TEST_NS" net-test -- sh -c "nc -vz myapp-svc.$TEST_NS.svc.cluster.local 8080 || true"
# Test HTTP (si l'app 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 succeeded (open) et wget renvoie 200 (ou statut attendu) sur /health.
Si TCP échoue mais que le DNS marche, revérifiez Endpoints et NetworkPolicies.
6) NetworkPolicies : autoriser explicitement
Si votre cluster applique des NetworkPolicies, la portée d'accès peut être limitée.
kubectl get networkpolicy -A
kubectl describe networkpolicy -n "$NAMESPACE"
Résultats attendus
- Aucune policy bloquante, ou des policies qui autorisent les sources attendues (labels/ports).
Approche de correction
- Ajoutez/ajustez une allow policy pour le selector de l'app et les ports requis. Appliquez via Helm si le chart gère ces policies. Revalidez avec net-test.
7) Ingress et exposition externe
Vérifiez règles, classe et statut de l'Ingress.
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).
- serviceName/servicePort alignés avec le Service.
- Une adresse figure dans status.loadBalancer.ingress ou le contrôleur publie une VIP atteignable.
Pistes de dépannage
- Corriger l'hôte, la classe ou le secret TLS dans values.yaml puis upgrade.
- Si l'adresse manque, vérifier le déploiement du contrôleur d'Ingress et son Service.
8) Services LoadBalancer et NodePort
Pour un Service de type LoadBalancer, vérifiez l'IP externe et les ports.
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.
Si EXTERNAL-IP reste Pending
- Vérifiez l'intégration cloud et les quotas. À titre temporaire, basculez en NodePort pour tester en interne (en environnement contrôlé).
9) Pare-feu hôtes et proxys
Si tout fonctionne en cluster mais pas depuis l'extérieur, inspectez pare-feu et proxys.
# Pare-feu Linux (sur les nœuds si vous avez accès)
sudo iptables -S | head -n 50 || true
sudo nft list ruleset | head -n 80 || true
sudo ufw status verbose || true
# Proxys sur poste ou jump-host
env | grep -i _proxy || true
Actions
- Autoriser les ports nécessaires sur les nœuds ou via le groupe de sécurité cloud.
- Configurer NO_PROXY pour inclure les sous-réseaux du cluster et .svc,.cluster.local si vos outils (ou Helm) doivent y accéder directement :
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 avec le réseau
Si le chart est piloté par values.yaml, confirmez comment les clés mappent les champs Service et Ingress. Utilisez helm template pour valider avant d'appliquer.
| Clé values Helm | Ressource | 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 | 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 | backend.service.port |
| networkPolicy.enabled | NetworkPolicy | Présence de la ressource |
Modes de panne et récupération (exemples)
- Échec de résolution DNS en cluster
- Symptôme : nslookup myapp-svc.ns-demo.svc.cluster.local échoue.
- Cause : CoreDNS indisponible, nom/namespace erroné.
- Fix : vérifier le déploiement coredns et corriger les FQDN.
- Vérifier : nslookup renvoie un enregistrement A.
- Rollback : si un changement du ConfigMap a cassé la résolution, restaurer la version précédente et redémarrer CoreDNS.
- Service sans endpoints
- Symptôme : kubectl get endpoints myapp-svc → <none>.
- Cause : selector/labels non concordants, pods non Ready.
- Fix : aligner labels/selectors dans values.yaml puis helm upgrade.
- Vérifier : endpoints listent des IPs avec le port correct.
- Incohérence port/targetPort
- Symptôme : TCP s'ouvre mais HTTP échoue ; l'app écoute ailleurs.
- Fix : aligner service.targetPort avec containerPort (ou nom de port partagé).
- Vérifier : wget sur /health renvoie le statut attendu.
- NetworkPolicy bloque le trafic
- Symptôme : OK depuis certains pods, KO depuis d'autres.
- Fix : ajouter une policy d'autorisation pour les namespaces/labels sources.
- Mauvaise configuration Ingress
- Symptôme : 404 ou erreur TLS sur https://app.example.local.
- Fix : corriger hosts, ingress.className et le secret TLS.
- External IP Pending (LoadBalancer)
- Symptôme : EXTERNAL-IP reste Pending, événements de provisioning.
- Fix : vérifier quotas/permissions cloud ou annotations requises ; NodePort temporaire si nécessaire.
- Proxy perturbe Helm ou les tests
- Symptôme : helm repo update instable ou tests incohérents.
- Fix : NO_PROXY pour domaines/CIDR in-cluster ; désactiver HTTP(S)_PROXY pour ces adresses.
Flux pratique de rollback et reprise
helm history "$RELEASE" -n "$NAMESPACE"
helm rollback "$RELEASE" REV -n "$NAMESPACE" --wait --timeout 5m
helm upgrade "$RELEASE" "$CHART_PATH" -n "$NAMESPACE" -f values.$RELEASE.yaml --wait --timeout 5m
Résultats attendus
- Le rollback se termine sans erreur, Services/Ingress retrouvent un état connu.
- Les corrections passent les vérifications décrites précédemment.
Vérification : contrôle de bout en bout
Après correction, rejouez ces contrôles minimalistes :
- Rendu vs exécution
- helm get manifest vs kubectl get svc/ing/ep : ports, selectors et hosts cohérents.
- DNS
- nslookup service.namespace.svc.cluster.local résout depuis le cluster.
- TCP et HTTP
- nc -vz service port ; wget http://service: port/health rendent un statut attendu.
- Ingress
- describe ingress : hôte et adresse corrects ; curl sur l'hôte retourne l'app.
- Accès externe
- Si LoadBalancer, EXTERNAL-IP répond sur le bon port.
Conclusion
Le Helm network troubleshooting consiste à valider les ressources Kubernetes rendues par Helm et leur interaction avec le DNS, les ports et le routage du cluster. En :
- Inventoriant versions, namespaces, releases et manifests rendus,
- Testant d'abord le DNS et la connectivité depuis le cluster,
- Vérifiant selectors de Service, Endpoints et mapping port/targetPort,
- Contrôlant NetworkPolicies, règles d'Ingress et IP externe,
- Et en appliquant les changements avec helm upgrade --wait tout en gardant helm rollback prêt,
vous isolez rapidement les causes racines et réparez en sécurité. Commencez par un test mesurable et étroit (par ex. résoudre le FQDN du service puis atteindre /health) avant d'élargir le périmètre. Ainsi, Helm networking, Helm DNS, Helm ports et Helm connectivity restent observables et maîtrisés, même face aux surprises réseau.