Contactez-nous

Service inaccessible : vérifier les sélecteurs et les ports

Diagnostiquez pourquoi un Service Kubernetes est inaccessible. Apprenez à vérifier les sélecteurs de labels, les ports (port, targetPort) et les Endpoints pour rétablir la connexion.

Mon Service existe, mais pourquoi ne répond-il pas ?

Les Services sont le mécanisme fondamental de Kubernetes pour exposer un ensemble de Pods sous une adresse IP et un nom DNS stables. Ils permettent le découplage et la découverte de services au sein du cluster (et parfois depuis l'extérieur). Cependant, il est fréquent de créer un Service, de vérifier qu'il existe avec `kubectl get svc`, mais de constater qu'il est impossible de le joindre ou qu'il ne route pas le trafic vers les Pods attendus.

Lorsque vous faites face à un Service inaccessible, deux des coupables les plus courants sont une mauvaise configuration des sélecteurs de labels (`selector`) ou une incohérence dans la définition des ports (`port`, `targetPort`). Ces éléments sont cruciaux car ils déterminent *quels* Pods le Service doit cibler et *comment* leur transférer le trafic.

Ce sous-chapitre vous guidera à travers les étapes de vérification des sélecteurs et des ports pour diagnostiquer et résoudre les problèmes d'accessibilité des Services Kubernetes.

Etape 1 : Vérifier la correspondance entre Sélecteur et Labels des Pods

Le lien fondamental entre un Service et les Pods qu'il doit exposer est établi par le champ `selector` dans la définition du Service et les `labels` appliqués aux Pods. Le Service recherche continuellement les Pods qui possèdent des labels correspondant exactement à son sélecteur.

Pour diagnostiquer un problème potentiel ici :

  1. Inspectez le Sélecteur du Service : Utilisez `kubectl describe service ` et repérez la ligne `Selector:`. Notez précisément les paires clé=valeur. Vous pouvez aussi utiliser `kubectl get service -o yaml` et regarder sous `spec.selector`.
    kubectl describe service mon-frontend-svc
    # Output (extrait):
    # Name:             mon-frontend-svc
    # Namespace:        default
    # Labels:           
    # Annotations:      
    # Selector:         app=frontend,tier=web
    # Type:             ClusterIP
    # ...
    Ici, le sélecteur exige les labels `app=frontend` ET `tier=web`.
  2. Vérifiez les Labels des Pods cibles : Listez les Pods que vous vous attendez à ce que le Service cible, en affichant leurs labels : `kubectl get pods --show-labels` ou filtrez directement : `kubectl get pods -l app=frontend`.
    kubectl get pods --show-labels
    # Output (extrait):
    # NAME                     READY   STATUS    RESTARTS   AGE   LABELS
    # mon-frontend-pod-123   1/1     Running   0          5m    app=frontend,tier=web
    # mon-frontend-pod-456   1/1     Running   0          5m    app=frontend,tier=web
    # mon-backend-pod-789    1/1     Running   0          10m   app=backend,tier=api
  3. Comparez rigoureusement : Les labels des Pods doivent correspondre exactement (clé et valeur) au sélecteur du Service. Une faute de frappe (`app=fronted` au lieu de `app=frontend`), une casse différente si les labels sont sensibles à la casse, ou un label manquant suffisent à rompre le lien. Dans l'exemple ci-dessus, les deux `mon-frontend-pod` correspondent, mais `mon-backend-pod` ne correspond pas.

Conséquence d'une non-correspondance : Si aucun Pod en cours d'exécution et prêt (`Ready`) ne correspond au sélecteur, l'objet Endpoints (ou EndpointSlice) associé au Service sera vide. Cela signifie que Kubernetes ne sait pas où envoyer le trafic destiné au Service.

Etape 2 : Examiner les Endpoints du Service

Le véritable routage du trafic par un Service ne se base pas directement sur le sélecteur, mais sur un objet distinct appelé `Endpoints` (ou le plus récent `EndpointSlice`) que Kubernetes maintient automatiquement à jour. Cet objet contient la liste des adresses IP et des ports des Pods qui correspondent *actuellement* au sélecteur du Service ET qui sont dans l'état `Ready`.

Pour vérifier cet objet :

kubectl get endpoints  [-n ]

(Pour EndpointSlices, plus efficaces pour les services ciblant de nombreux pods : `kubectl get endpointslice -l kubernetes.io/service-name=`)

Examinez la colonne `ENDPOINTS` :

NAME               ENDPOINTS                                AGE
mon-frontend-svc   10.1.2.3:8080,10.1.2.4:8080              15m

Ici, le Service a trouvé deux Pods prêts (`10.1.2.3` et `10.1.2.4`) et sait qu'il doit router le trafic vers le port `8080` de ces Pods.

Le signe d'alerte majeur est une liste d'Endpoints vide :
NAME               ENDPOINTS   AGE
mon-frontend-svc         15m

Si vous voyez `` ou une liste vide, cela confirme presque certainement un problème :

  • Soit le sélecteur du Service ne correspond à aucun label de Pod (retournez à l'étape 1).
  • Soit les Pods qui correspondent au sélecteur ne sont pas encore dans l'état `Ready` (ils sont peut-être encore en `ContainerCreating`, `Pending`, ou échouent à leurs Readiness Probes). Vérifiez l'état des Pods avec `kubectl get pods -l `.

Etape 3 : Valider la configuration des Ports

Une fois que vous êtes sûr que le Service est correctement lié aux bons Pods via le sélecteur et que les Endpoints sont peuplés, le problème peut résider dans la configuration des ports. Il est essentiel de comprendre les différents ports dans la définition d'un Service :

  • `port` : C'est le port sur lequel le Service lui-même écoute à l'intérieur du cluster (sur son IP virtuelle ClusterIP). C'est le port que les autres Pods du cluster utiliseront pour contacter ce Service.
  • `targetPort` : C'est le port sur lequel l'application *à l'intérieur du conteneur* écoute réellement le trafic. Kubernetes redirige le trafic arrivant sur le `port` du Service vers le `targetPort` des Pods listés dans les Endpoints. Ce `targetPort` doit correspondre exactement au port exposé par votre application dans son conteneur.
  • `nodePort` : Uniquement pour les Services de type `NodePort` ou `LoadBalancer`. C'est un port statique (dans une plage par défaut 30000-32767) ouvert sur l'adresse IP de *chaque* Noeud du cluster. Le trafic arrivant sur ce `nodePort` est ensuite routé vers le `port` interne du Service, puis vers le `targetPort` des Pods.

Utilisez `kubectl describe service ` ou `kubectl get service -o yaml` pour vérifier ces valeurs.

# Extrait de kubectl get svc my-service -o yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - name: http
    port: 80         # Le Service écoute sur le port 80
    protocol: TCP
    targetPort: 8080   # Le conteneur applicatif doit écouter sur le port 8080
  selector:
    app: my-app
  type: ClusterIP
Erreurs courantes liées aux ports :
  • Incohérence `targetPort` / Application : L'erreur la plus fréquente. Le `targetPort` dans le Service est défini à `80`, mais l'application dans le conteneur écoute sur le `8080` (ou vice-versa). Le trafic arrive au Pod mais n'atteint jamais l'application. Vérifiez la configuration de votre serveur web/application ou le `Dockerfile` (`EXPOSE`) pour connaître le port réel d'écoute.
  • Oubli ou mauvaise définition du `targetPort` : Si `targetPort` n'est pas défini, il prend par défaut la même valeur que `port`. Si votre application écoute sur un port différent, cela échouera. Il est souvent plus clair de définir explicitement `targetPort`, qui peut aussi être un nom de port défini dans la section `ports` du conteneur dans le Pod/Déploiement.
  • Confusion lors de l'accès : Tenter d'accéder directement au `targetPort` de l'IP du Service (ne fonctionnera pas). Utiliser le `port` pour l'accès ClusterIP. Oublier d'utiliser le `nodePort` (et l'IP d'un Noeud) pour accéder à un Service NodePort depuis l'extérieur du cluster.
Solution : Assurez-vous que la valeur de `targetPort` dans la définition du Service correspond exactement au port sur lequel votre application écoute dans le conteneur. Corrigez le manifeste du Service ou la configuration de l'application/Dockerfile, puis réappliquez (`kubectl apply`).

Checklist rapide pour les Services inaccessibles

Face à un Service Kubernetes qui ne répond pas :

  1. Existe-t-il ? `kubectl get svc `
  2. Le Sélecteur est-il correct ? `kubectl describe svc ` (notez le `Selector`).
  3. Les Pods ont-ils les bons Labels ? `kubectl get pods --show-labels` ou `kubectl get pods -l ` (vérifiez la correspondance exacte).
  4. Les Endpoints sont-ils peuplés ? `kubectl get endpoints ` (doit lister des IP:Port, pas ``).
  5. Les Pods cibles sont-ils `Ready` ? `kubectl get pods -l ` (vérifiez la colonne `READY`, doit être `1/1`, `2/2`, etc.).
  6. Les Ports sont-ils cohérents ? `kubectl describe svc ` (vérifiez `Port`, `TargetPort`, `NodePort`).
  7. Le `targetPort` correspond-il au port d'écoute de l'application dans le conteneur ? (Vérifiez la configuration de l'application ou le Dockerfile).
  8. Utilisez-vous le bon port/IP pour accéder au Service ? (ClusterIP:`:` ou `:` ; NodePort:`:`).

En vérifiant méthodiquement les sélecteurs et les ports, ainsi que l'état des Pods sous-jacents et la liste des Endpoints, vous pouvez résoudre la majorité des problèmes empêchant vos Services Kubernetes de fonctionner correctement.