Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Services Kubernetes : exposer et connecter vos applications

14 min de lecture

logo kubernetes

Un Service Kubernetes permet d’exposer un ou plusieurs Pods via une adresse IP stable et un nom DNS interne. Comme les Pods sont éphémères et changent d’adresse IP, le Service fournit un point d’accès durable pour la communication réseau entre applications ou vers l’extérieur du cluster. Ce guide vous montre comment créer des Services, choisir le bon type (ClusterIP, NodePort, LoadBalancer) et diagnostiquer les problèmes de connectivité.

Prérequis : un cluster Kubernetes fonctionnel avec au moins un Deployment ou des Pods.

  • Créer un Service avec kubectl expose et avec un fichier YAML
  • Choisir le bon type : ClusterIP, NodePort, LoadBalancer, Headless
  • Comprendre la résolution DNS entre Pods et Services
  • Utiliser les labels/selectors pour cibler les bons Pods
  • Diagnostiquer quand un Service ne fonctionne pas

Un Service est une abstraction réseau qui expose un groupe de Pods via une adresse IP stable et un nom DNS.

Pour un débutant, retenez simplement :

  • Les Pods changent d’IP à chaque recréation
  • Le Service garde une IP fixe qui redirige vers les Pods
  • Les autres Pods appellent le Service par son nom, pas par IP

Sans Services, chaque Pod devrait connaître l’adresse IP des autres Pods — une adresse qui change à chaque redémarrage.

Les Services résolvent ce problème en fournissant :

FonctionnalitéDescription
IP stableUne adresse fixe qui ne change pas quand les Pods sont recréés
Nom DNSUn nom comme backend-service au lieu d’une IP
Load balancingRépartition automatique du trafic entre plusieurs Pods
DécouverteLes Pods trouvent les autres services par leur nom

Une application web avec :

  • Un frontend (React)
  • Un backend (API Node.js)
  • Une base de données (PostgreSQL)

Le frontend appelle backend-service:8080 au lieu de chercher l’IP du Pod backend. Si le Pod backend redémarre avec une nouvelle IP, le Service redirige automatiquement.

La façon la plus rapide de créer un Service pour un Deployment existant :

Fenêtre de terminal
kubectl expose deployment nginx --name=nginx-service --port=80 --target-port=80

Résultat : un Service ClusterIP nommé nginx-service qui expose le port 80.

Vérifiez sa création :

Fenêtre de terminal
kubectl get svc nginx-service
Sortie
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.43.7.235 <none> 80/TCP 5s

Pour un contrôle total, créez un fichier manifest :

nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP

Les champs essentiels :

ChampDescription
selectorLabels des Pods à cibler (ici app: nginx)
portPort exposé par le Service
targetPortPort sur lequel écoutent les Pods
typeType de Service (ClusterIP par défaut)

Appliquez-le :

Fenêtre de terminal
kubectl apply -f nginx-service.yaml

Une fois votre Service créé, vérifiez qu’il fonctionne.

Fenêtre de terminal
kubectl get svc -o wide
Sortie
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-service ClusterIP 10.43.7.235 <none> 80/TCP 2m app=nginx

Les colonnes importantes :

ColonneSignification
TYPEClusterIP, NodePort, LoadBalancer…
CLUSTER-IPAdresse IP interne du Service
PORT(S)Ports exposés
SELECTORLabels utilisés pour trouver les Pods
Fenêtre de terminal
kubectl describe svc nginx-service

Cette commande montre :

  • Endpoints : IPs des Pods ciblés par le Service
  • Session Affinity : sticky sessions ou non
  • Events : historique (rarement utile pour les Services)
Sortie (extrait)
Name: nginx-service
Selector: app=nginx
Type: ClusterIP
IP: 10.43.7.235
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.42.0.9:80,10.42.1.8:80,10.42.1.9:80
Fenêtre de terminal
kubectl get endpoints nginx-service
Sortie
NAME ENDPOINTS AGE
nginx-service 10.42.0.9:80,10.42.1.8:80,10.42.1.9:80 5m

Chaque IP correspond à un Pod qui recevra du trafic.

Kubernetes propose quatre types de Services selon vos besoins d’exposition.

Le Service est accessible uniquement depuis l’intérieur du cluster.

spec:
type: ClusterIP # ou omettez, c'est le défaut

Cas d’usage : communication entre microservices (backend ↔ base de données).

┌─────────────────────────────────────────────┐
│ Cluster │
│ │
│ Frontend Pod ──────► backend-service │
│ │ │
│ ▼ │
│ Backend Pods │
└─────────────────────────────────────────────┘

Le Service est accessible via un port sur chaque nœud du cluster.

spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080 # optionnel, entre 30000-32767

Accès : http://<IP-du-noeud>:30080

Cas d’usage : tests locaux, environnements sans cloud provider.

┌─────────────────────────────────────────────────┐
│ │
│ Internet/Réseau externe │
│ │ │
│ ▼ :30080 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Node 1 │ │ Node 2 │ │
│ │ :30080 │ │ :30080 │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ └────────┬──────────┘ │
│ ▼ │
│ Service (ClusterIP) │
│ │ │
│ ▼ │
│ Pods │
└─────────────────────────────────────────────────┘

Le Service demande un équilibreur de charge externe au cloud provider (AWS, GCP, Azure…).

spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80

Accès : via l’IP externe fournie par le cloud (EXTERNAL-IP).

Cas d’usage : applications en production sur le cloud.

Fenêtre de terminal
kubectl get svc
Sortie
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service LoadBalancer 10.43.7.235 203.0.113.50 80:30262/TCP 2m
BesoinType recommandé
Communication interneClusterIP
Test local sans cloudNodePort
Production sur cloudLoadBalancer

Le type ExternalName est à part : il ne sélectionne pas de Pods et ne fait pas de proxy. Il redirige simplement vers un nom DNS externe.

spec:
type: ExternalName
externalName: database.example.com

Cas d’usage : pointer vers une base de données managée (RDS, Cloud SQL…). Les Pods appellent external-db et sont redirigés vers database.example.com.

Un Headless Service (clusterIP: None) ne possède pas d’IP de cluster. Le DNS retourne directement les IPs des Pods au lieu de l’IP du Service.

spec:
clusterIP: None
selector:
app: nginx
Service normalHeadless Service
DNS → IP du ServiceDNS → IPs des Pods
Load balancing par kube-proxyClient choisit le Pod

Cas d’usage : bases de données stateful, StatefulSets avec identité réseau stable. Voir le guide StatefulSets pour plus de détails.

Kubernetes crée automatiquement des enregistrements DNS pour chaque Service.

<service-name>.<namespace>.svc.cluster.local
Appel depuisNom à utiliser
Même namespacenginx-service
Autre namespacenginx-service.production
Nom complet (FQDN)nginx-service.production.svc.cluster.local
Fenêtre de terminal
kubectl run test-dns --image=busybox:1.36 --rm -it --restart=Never -- nslookup nginx-service
Sortie
Server: 10.43.0.10
Address: 10.43.0.10:53
Name: nginx-service.default.svc.cluster.local
Address: 10.43.7.235

Par défaut, kube-proxy répartit le trafic aléatoirement. Pour garder un client sur le même Pod, ajoutez sessionAffinity: ClientIP :

spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 600

Cas d’usage : websockets, sessions en mémoire. Attention : ne fonctionne pas bien derrière un proxy qui masque l’IP client.

Une question fréquente : quand utiliser un Service, quand utiliser un Ingress ?

ServiceIngress
CoucheL4 (TCP/UDP)L7 (HTTP/HTTPS)
RoutagePar IP/portPar path, host, headers
TLSNonOui (terminaison)
UsageCommunication interne ou exposition simpleAPI publique, sites web

Règle simple : utilisez un Service pour la communication interne ou l’exposition basique, un Ingress pour du routage HTTP avancé.

Un Service Kubernetes est un outil Layer 4 (TCP/UDP). Il a des limitations :

BesoinSolution
Routage HTTP (path, host)Ingress
Terminaison TLSIngress + cert-manager
Filtrage de sécuritéNetworkPolicies
Rate limiting, circuit breakerService mesh

Symptôme : Endpoints: <none> dans kubectl describe svc.

Fenêtre de terminal
# Vérifier les labels des Pods
kubectl get pods --show-labels
# Comparer avec le selector du Service
kubectl get svc nginx-service -o jsonpath='{.spec.selector}'

Cause : le selector ne correspond pas aux labels des Pods.

Symptôme : curl nginx-service timeout ou connexion refusée.

Fenêtre de terminal
kubectl describe svc nginx-service | grep TargetPort
kubectl exec -it nginx-pod -- netstat -tlnp

Cause : le targetPort ne correspond pas au port de l’application.

Symptôme : nslookup nginx-service échoue.

Fenêtre de terminal
kubectl -n kube-system get pods -l k8s-app=kube-dns
kubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- nslookup kubernetes
Fenêtre de terminal
kubectl run debug --image=nicolaka/netshoot --rm -it --restart=Never -- bash

Depuis ce Pod : curl, nslookup, dig, tcpdump

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

7 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  1. Un Service donne une IP stable et un nom DNS à un groupe de Pods
  2. Le selector doit correspondre aux labels des Pods (sinon pas d’endpoints)
  3. ClusterIP (défaut) : communication interne uniquement
  4. NodePort : exposition sur un port de chaque nœud (30000-32767)
  5. LoadBalancer : demande un équilibreur externe au cloud provider
  6. Headless (clusterIP: None) : DNS retourne directement les IPs des Pods
  7. EndpointSlices : API moderne qui stocke les adresses des Pods
  8. Un Service ne fait pas de routage HTTP, TLS ou filtrage sécurité — utilisez Ingress et NetworkPolicies

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn