You are currently viewing Kubernetes Services : guide complet pour bien les utiliser

Kubernetes Services : guide complet pour bien les utiliser

  • Auteur/autrice de la publication :
  • Post category:DevOps

Dans cet article

  • Un Service Kubernetes est une abstraction réseau qui expose un ensemble de Pods via une adresse IP stable et un DNS interne
  • Il existe 4 types de Services : ClusterIP, NodePort, LoadBalancer et ExternalName, chacun adapté à un cas d’usage précis
  • La différence entre port, targetPort et nodePort est essentielle pour router correctement le trafic vers vos conteneurs
  • Un Ingress ne remplace pas un Service : il agit comme un reverse proxy HTTP/HTTPS devant un ou plusieurs Services
  • Les labels et selectors constituent le mécanisme de découverte automatique qui relie un Service à ses Pods cibles
  • En production, combiner un Service LoadBalancer avec un Ingress Controller permet de gérer le routage L7 et le TLS de façon centralisée

Quand j’ai commencé à enseigner Kubernetes à mes étudiants en BTS SIO, la notion de Service était systématiquement celle qui générait le plus de questions. On déploie des Pods, on comprend les Deployments, puis arrive la question fatidique : comment accéder à mon application ? C’est précisément le rôle des kubernetes services, et je vous propose de les démystifier ensemble dans ce guide complet.

Que vous prépariez une certification, un projet professionnel ou que vous cherchiez simplement à comprendre le réseau Kubernetes, cet article vous donnera toutes les clés pour maîtriser les Services, du concept théorique jusqu’au déploiement en production.

Quel est le principe de Kubernetes et de ses Services ?

Avant de plonger dans les Services, rappelons rapidement le principe de Kubernetes. Kubernetes est un orchestrateur de conteneurs open source, initialement développé par Google et maintenant maintenu par la Cloud Native Computing Foundation (CNCF). Son rôle est d’automatiser le déploiement, la mise à l’échelle et la gestion d’applications conteneurisées sur un cluster de machines.

Le principe fondamental de Kubernetes repose sur un modèle déclaratif : vous décrivez l’état souhaité de votre infrastructure dans des fichiers YAML, et Kubernetes se charge de maintenir cet état en permanence. Si un Pod tombe, Kubernetes en recrée un automatiquement. Si la charge augmente, il peut scaler horizontalement.

Un développeur configure des Services Kubernetes depuis son terminal avec kubectl
Un développeur configure des Services Kubernetes depuis son terminal avec kubectl

Mais voilà le problème : les Pods sont éphémères par nature. Chaque fois qu’un Pod est recréé, il obtient une nouvelle adresse IP. Impossible donc de se fier à l’IP d’un Pod pour y accéder. C’est exactement pour résoudre ce problème que les Services Kubernetes existent. Ils fournissent une abstraction réseau stable devant un ensemble de Pods, avec une IP fixe et un nom DNS interne qui ne changent pas, même quand les Pods sous-jacents sont remplacés.

Si vous travaillez déjà avec des outils d’infrastructure cloud computing, vous retrouverez des concepts familiers : load balancing, discovery service et routage réseau. Kubernetes les intègre nativement grâce à ses Services.

C’est quoi un Service Kubernetes exactement ?

Un Service Kubernetes est une ressource API qui définit un point d’accès réseau stable vers un ensemble logique de Pods. Concrètement, il agit comme un load balancer interne qui distribue le trafic vers les Pods correspondant à un ensemble de labels définis via un selector.

Voici ce qui se passe quand vous créez un Service :

  1. Kubernetes attribue au Service une ClusterIP (adresse IP virtuelle interne au cluster)
  2. Le composant kube-proxy configure les règles iptables ou IPVS sur chaque nœud pour rediriger le trafic vers les Pods cibles
  3. Un enregistrement DNS interne est créé sous la forme nom-service.namespace.svc.cluster.local
  4. Le Service surveille en permanence les Pods via les labels : si un Pod disparaît ou apparaît, la liste des endpoints est mise à jour automatiquement

C’est ce mécanisme de découverte de service (service discovery) qui rend Kubernetes si puissant pour les architectures microservices. Chaque microservice peut appeler les autres par leur nom DNS, sans se soucier de l’infrastructure sous-jacente.

Pour illustrer, imaginez une application web avec un frontend et un backend. Le frontend n’a pas besoin de connaître les adresses IP des Pods backend. Il appelle simplement http://backend-api:8080, et le Service Kubernetes se charge du reste. Cette approche rappelle d’ailleurs le fonctionnement des reverse proxies comme Nginx ou Apache, mais de façon totalement automatisée et intégrée au cluster.

Les 4 types de Services Kubernetes détaillés

Kubernetes propose quatre types de Services, chacun répondant à un besoin d’exposition différent. Voici un tableau comparatif pour y voir clair d’un coup d’œil :

Type de Service Accessibilité Cas d’usage principal Port exposé
ClusterIP Interne au cluster uniquement Communication inter-microservices Port interne virtuel
NodePort Externe via IP du nœud + port fixe Tests, développement, accès direct 30000-32767
LoadBalancer Externe via IP publique du cloud Production sur cloud provider Port standard (80, 443)
ExternalName Redirection DNS vers service externe Intégration services hors cluster Aucun (alias CNAME)

ClusterIP : le Service par défaut

ClusterIP est le type par défaut. Quand vous créez un Service sans préciser de type, c’est un ClusterIP. Il attribue une IP virtuelle accessible uniquement depuis l’intérieur du cluster. C’est le choix idéal pour la communication entre microservices : votre API backend, votre base de données, votre cache Redis, tous ces composants internes n’ont pas besoin d’être exposés à l’extérieur.

NodePort : l’accès externe simple

Le Kubernetes NodePort étend le ClusterIP en ouvrant un port statique (entre 30000 et 32767) sur chaque nœud du cluster. Vous pouvez alors accéder au Service via <IP-du-noeud>:<NodePort>. C’est pratique pour le développement et les tests, mais je le déconseille en production : exposer des ports élevés sur vos nœuds n’est ni élégant ni sécurisé.

LoadBalancer : la solution cloud

Sur un cloud provider (AWS, GCP, Azure, ou toute infrastructure cloud), le type LoadBalancer provisionne automatiquement un load balancer externe qui distribue le trafic vers vos Pods. C’est le type le plus utilisé en production pour exposer des applications au monde extérieur. Chaque Service LoadBalancer crée son propre load balancer, ce qui peut coûter cher si vous en avez beaucoup : c’est là qu’un Ingress Controller entre en jeu.

ExternalName : le pont vers l’extérieur

ExternalName est un cas particulier qui ne route pas de trafic. Il crée simplement un alias DNS (CNAME) vers un service externe au cluster. Par exemple, vous pouvez créer un Service database qui pointe vers db.example.com. Si vous migrez ultérieurement cette base dans le cluster, il suffira de changer le type de Service sans modifier le code de vos applications.

Port, targetPort et nodePort : comprendre les différences

La confusion entre port, targetPort et nodePort est probablement l’erreur la plus fréquente que je vois chez mes étudiants. Clarifions cela une bonne fois pour toutes.

Schéma d'architecture réseau Kubernetes dessiné sur un tableau blanc en salle de réunion
Schéma d’architecture réseau Kubernetes dessiné sur un tableau blanc en salle de réunion

Dans une définition de Service, vous rencontrez jusqu’à trois valeurs de port :

  • port : c’est le port sur lequel le Service lui-même écoute à l’intérieur du cluster. Les autres Pods utilisent ce port pour contacter le Service. Si votre Service s’appelle backend et que port: 80, les autres Pods appellent backend:80
  • targetPort : c’est le port sur lequel votre conteneur écoute réellement dans le Pod. Si votre application Node.js écoute sur le port 3000, alors targetPort: 3000. Le Service traduit le trafic de port vers targetPort
  • nodePort : uniquement pour les Services de type NodePort ou LoadBalancer. C’est le port ouvert sur chaque nœud physique du cluster (entre 30000 et 32767). Le trafic arrivant sur ce port est redirigé vers le port du Service, puis vers le targetPort du Pod

Voici le flux complet du trafic :

Client → nodePort (30080 sur le nœud) → port (80 du Service) → targetPort (3000 du Pod)

En résumé : port est l’entrée du Service, targetPort est la sortie vers le Pod, et nodePort est l’entrée depuis l’extérieur du cluster. Si vous omettez targetPort, Kubernetes utilise la même valeur que port par défaut.

Ingress vs Service : deux rôles complémentaires

Une question revient constamment dans mes cours : quelle est la différence entre un Ingress et un Service ? La réponse courte : un Ingress n’est pas un type de Service. Ce sont deux ressources complémentaires qui opèrent à des niveaux réseau différents.

Un Service opère au niveau L4 (transport) : il route le trafic TCP/UDP vers des Pods en se basant sur l’IP et le port. Un Ingress opère au niveau L7 (application) : il route le trafic HTTP/HTTPS en se basant sur le nom d’hôte et le chemin URL.

Critère Service (LoadBalancer) Ingress
Couche réseau L4 (TCP/UDP) L7 (HTTP/HTTPS)
Routage Par IP et port Par host et path URL
TLS/SSL Géré côté application Terminaison TLS centralisée
Coût cloud 1 load balancer par Service 1 seul load balancer pour tout
Protocoles TCP, UDP, SCTP HTTP, HTTPS, gRPC
Prérequis Aucun Ingress Controller installé

En pratique, un Ingress a besoin d’un Service de type ClusterIP devant chaque application pour fonctionner. L’architecture typique en production ressemble à ceci :

Internet → LoadBalancer → Ingress Controller (Nginx/Traefik)
  → /api → Service ClusterIP "api" → Pods API
  → /app → Service ClusterIP "frontend" → Pods Frontend

L’avantage principal de l’Ingress est économique et pratique : au lieu de payer un load balancer cloud par application, vous n’en avez qu’un seul devant l’Ingress Controller, qui route ensuite intelligemment le trafic. Ajoutez à cela la gestion centralisée des certificats TLS avec cert-manager, et vous obtenez une architecture réseau propre et maintenable.

Pour automatiser le déploiement de cette stack, je recommande d’utiliser un pipeline GitHub Actions CI/CD qui applique vos manifestes Kubernetes de façon reproductible.

Créer un Service Kubernetes : exemples pratiques pas à pas

Passons à la pratique avec des Kubernetes exemples concrets. Je vais vous montrer comment créer chaque type de Service avec les manifestes YAML correspondants.

Exemple 1 : Service ClusterIP pour une API interne

apiVersion: v1
kind: Service
metadata:
  name: api-backend
  namespace: production
  labels:
    app: api-backend
spec:
  type: ClusterIP
  selector:
    app: api-backend
    tier: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http

Ce Service expose les Pods ayant les labels app: api-backend et tier: backend sur le port 80 du cluster. Le trafic est redirigé vers le port 8080 des conteneurs. Les autres microservices peuvent accéder à cette API via http://api-backend.production.svc.cluster.local ou simplement http://api-backend depuis le même namespace.

Fichiers YAML de configuration des Services Kubernetes dans un éditeur de code
Fichiers YAML de configuration des Services Kubernetes dans un éditeur de code

Exemple 2 : Service NodePort pour le développement

apiVersion: v1
kind: Service
metadata:
  name: frontend-dev
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
      nodePort: 30080

Avec ce manifest, votre application React (qui écoute sur le port 3000) sera accessible depuis votre navigateur via http://<ip-noeud>:30080. Idéal pour vos Kubernetes exercices en environnement de développement local avec Minikube ou kind.

Exemple 3 : Service LoadBalancer pour la production

apiVersion: v1
kind: Service
metadata:
  name: webapp-prod
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  selector:
    app: webapp
    environment: production
  ports:
    - protocol: TCP
      port: 443
      targetPort: 8443
      name: https
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http

Ce Service provisionne un Network Load Balancer AWS et expose l’application sur les ports 80 et 443. Les annotations varient selon le cloud provider utilisé.

Exemple 4 : Service multi-ports avec nommage

Quand un Pod expose plusieurs ports (API HTTP + métriques Prometheus, par exemple), nommez chaque port pour plus de clarté :

apiVersion: v1
kind: Service
metadata:
  name: app-complet
spec:
  selector:
    app: mon-application
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
    - name: metrics
      protocol: TCP
      port: 9090
      targetPort: 9090
    - name: grpc
      protocol: TCP
      port: 50051
      targetPort: 50051

Pour appliquer ces manifestes, utilisez la commande kubectl apply -f service.yaml et vérifiez avec kubectl get svc. Si vous automatisez vos déploiements, un script Bash peut orchestrer l’application de vos manifestes dans le bon ordre.

Bonnes pratiques pour les Services Kubernetes en production

Après plusieurs années à déployer des services kubernetes en production et à accompagner mes étudiants dans leurs projets, voici les pratiques que je recommande systématiquement.

Nommage et organisation

Adoptez une convention de nommage cohérente pour vos Services. J’utilise le format <app>-<composant> : shop-api, shop-frontend, shop-cache. Regroupez les Services liés dans un même namespace et utilisez des labels structurés (app, tier, environment) pour faciliter le filtrage et le monitoring.

Sécurité réseau avec les NetworkPolicies

Par défaut, tous les Pods peuvent communiquer entre eux dans un cluster Kubernetes. En production, c’est un risque. Utilisez des NetworkPolicies pour restreindre le trafic :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
spec:
  podSelector:
    matchLabels:
      app: api-backend
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - port: 8080

Cette politique n’autorise que les Pods frontend à contacter l’API backend sur le port 8080. Tout autre trafic entrant est bloqué.

Health checks et readiness

Un Service n’envoie du trafic qu’aux Pods dont la readinessProbe est en succès. Configurez toujours des probes de readiness sur vos Deployments pour éviter d’envoyer du trafic vers des Pods qui ne sont pas encore prêts à servir des requêtes. C’est un mécanisme fondamental pour les déploiements sans interruption (rolling updates).

Headless Services pour le stateful

Pour les applications stateful (bases de données, clusters Elasticsearch), utilisez un Headless Service (clusterIP: None). Au lieu de load-balancer le trafic, il crée un enregistrement DNS pour chaque Pod individuel, permettant un accès direct. C’est essentiel pour le Kubernetes stockage persistant et les StatefulSets où chaque instance a une identité unique.

Si vous hésitez entre un déploiement cloud ou local pour vos clusters Kubernetes, consultez notre comparatif on-premises vs cloud computing pour faire le bon choix selon votre contexte.

Dépannage des Services Kubernetes : erreurs courantes

En formation comme en production, certains problèmes reviennent systématiquement. Voici mon guide de dépannage pour les situations les plus fréquentes.

Le Service ne route pas le trafic

C’est le problème numéro un. Dans 90 % des cas, c’est un problème de selector. Vérifiez que les labels du selector du Service correspondent exactement aux labels de vos Pods :

# Vérifier les endpoints du Service
kubectl get endpoints mon-service

# Si la liste est vide, les labels ne matchent pas
kubectl describe svc mon-service
kubectl get pods --show-labels

Comparez les labels affichés. Une simple coquille (app: backend vs app: back-end) suffit à casser le routage.

Erreur « Connection refused » ou timeout

Si les endpoints existent mais que la connexion échoue, vérifiez dans cet ordre :

  1. Le targetPort est-il correct ? Il doit correspondre au port sur lequel votre application écoute dans le conteneur
  2. Le Pod est-il ready ? Vérifiez avec kubectl get pods que le statut est Running et que la colonne READY affiche le bon ratio
  3. L’application écoute-t-elle sur 0.0.0.0 ? Une application qui écoute sur 127.0.0.1 (localhost) ne sera pas accessible via le Service
  4. Une NetworkPolicy bloque-t-elle le trafic ? Vérifiez avec kubectl get networkpolicies

DNS interne qui ne résout pas

Si nslookup mon-service échoue depuis un Pod, vérifiez que le composant CoreDNS fonctionne correctement :

kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns

Vérifiez aussi que vous utilisez le bon FQDN. Depuis un Pod dans le namespace default qui veut accéder à un Service dans le namespace production, utilisez mon-service.production.svc.cluster.local.

Pour stocker vos manifestes et configurations, je recommande un dépôt Git dédié. Consultez la documentation officielle Kubernetes sur les Services pour une référence complète des options de configuration disponibles.

D’ailleurs, si vous envisagez une carrière dans le DevOps ou l’administration de clusters Kubernetes, sachez qu’il est tout à fait possible de travailler dans l’informatique sans diplôme en validant des certifications comme le CKA (Certified Kubernetes Administrator). Et pour décrocher le poste, pensez à bien préparer votre entretien technique sur les concepts d’orchestration.

À retenir

  • Utilisez ClusterIP pour toute communication interne entre microservices et réservez NodePort au développement
  • Vérifiez systématiquement la correspondance des labels entre le selector du Service et les Pods avec kubectl get endpoints
  • Combinez un Service LoadBalancer + Ingress Controller en production pour centraliser le routage HTTP et la terminaison TLS
  • Configurez des readinessProbes sur tous vos Deployments pour éviter d’envoyer du trafic vers des Pods non prêts
  • Appliquez des NetworkPolicies pour restreindre les flux réseau et respecter le principe du moindre privilège

Questions fréquentes


C’est quoi un service Kubernetes ?

Un Service Kubernetes est une ressource API qui fournit un point d’accès réseau stable (IP fixe + nom DNS) vers un ensemble de Pods sélectionnés par des labels. Il agit comme un load balancer interne qui distribue le trafic et met à jour automatiquement ses endpoints quand des Pods sont créés ou supprimés. C’est le mécanisme central de découverte de service dans un cluster Kubernetes.


Quel est le principe de Kubernetes ?

Kubernetes est un orchestrateur de conteneurs qui repose sur un modèle déclaratif : vous décrivez l’état souhaité de vos applications dans des fichiers YAML (nombre de réplicas, ressources, réseau) et Kubernetes maintient automatiquement cet état. Il gère le déploiement, la mise à l’échelle, la haute disponibilité et le réseau de vos applications conteneurisées sur un cluster de machines.


Quelle est la différence entre un ingress et un service dans Kubernetes ?

Un Service opère au niveau L4 (transport) et route le trafic TCP/UDP par IP et port. Un Ingress opère au niveau L7 (application) et route le trafic HTTP/HTTPS par nom d’hôte et chemin URL. L’Ingress nécessite un Ingress Controller (Nginx, Traefik) et s’appuie sur des Services ClusterIP pour atteindre les Pods. En production, on combine généralement les deux pour centraliser le routage et la terminaison TLS.


Quelle est la différence entre un port de service Kubernetes et un port cible ?

Le port est celui sur lequel le Service écoute à l’intérieur du cluster : c’est l’adresse utilisée par les autres Pods pour contacter le Service. Le targetPort (port cible) est celui sur lequel l’application écoute réellement dans le conteneur. Le Service redirige le trafic du port vers le targetPort. Par exemple, un Service peut écouter sur le port 80 et rediriger vers le targetPort 3000 d’une application Node.js.


Comment choisir le bon type de Service Kubernetes ?

Pour la communication interne entre microservices, utilisez ClusterIP (type par défaut). Pour des tests locaux avec accès externe rapide, utilisez NodePort. Pour la production sur un cloud provider, utilisez LoadBalancer combiné à un Ingress Controller pour le routage HTTP. Pour pointer vers un service externe au cluster, utilisez ExternalName. En règle générale, évitez NodePort en production au profit de LoadBalancer + Ingress.


Comment débugger un Service Kubernetes qui ne fonctionne pas ?

Commencez par vérifier les endpoints avec kubectl get endpoints mon-service. Si la liste est vide, les labels du selector ne correspondent pas aux labels des Pods. Vérifiez ensuite que le targetPort correspond bien au port d’écoute de votre application, que l’application écoute sur 0.0.0.0 (et non 127.0.0.1), et qu’aucune NetworkPolicy ne bloque le trafic. Utilisez kubectl describe svc et kubectl get pods --show-labels pour comparer.


Lucie Moreau
Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.

Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.