3.3 · Parcours 3 — Réseau et exposition (CKAD · CKA)
NodePort, LoadBalancer et endpoints
Leçon théorique · questionnaire de validation · gratuit, dans le navigateur
Un Service ClusterIP ne se joint que depuis l'intérieur du cluster. Pour qu'un utilisateur, un partenaire ou un autre système extérieur atteigne votre application, Kubernetes propose d'autres types de Services, et un objet dédié au web, l'Ingress. Cette leçon fait le tour des options, de ce qu'elles coûtent et de quand les choisir.
Ce que vous saurez à la fin : distinguer ClusterIP, NodePort, LoadBalancer, ExternalName et les Services headless, expliquer ce qu'il y a sous le capot (kube-proxy, EndpointSlices), et choisir la bonne exposition pour un besoin donné.
1. Les types de Service
┌──────────────── cluster ─────────────────┐
Internet ──► LB ──► │ nœud:30080 (NodePort) ──► ClusterIP ──► pods │
└──────────────────────────────────────────┘
Chaque type s'empile sur le précédent :
| Type | Ce qu'il ajoute | Joignable depuis |
|---|---|---|
| ClusterIP (défaut) | une IP virtuelle interne et un nom DNS | l'intérieur du cluster |
| NodePort | un port (par défaut entre 30000 et 32767) ouvert sur chaque nœud | quiconque atteint l'IP d'un nœud |
| LoadBalancer | un répartiteur de charge externe, créé par le fournisseur cloud (ou MetalLB sur site), devant les NodePorts | Internet ou le réseau de l'entreprise, via une IP dédiée |
| ExternalName | un simple alias DNS (CNAME) vers un nom externe | — (aucun trafic ne transite par Kubernetes) |
NodePort
spec:
type: NodePort
selector: {app: web}
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # facultatif : sinon un port libre est choisi
C'est simple, mais il faut que les clients connaissent l'IP d'un nœud, que les nœuds soient exposés, et ils ne disposent que de ports « bizarres » (30000+). On le voit surtout en test, ou derrière un répartiteur géré à la main.
LoadBalancer
spec:
type: LoadBalancer
selector: {app: web}
ports: [{port: 80, targetPort: 8080}]
kubectl get service web # colonne EXTERNAL-IP, d'abord <pending>, puis une IP
Kubernetes ne crée pas lui-même le répartiteur : il le demande à un contrôleur (celui du cloud, ou MetalLB, kube-vip… sur site). Sans contrôleur, l'adresse externe reste <pending> pour toujours. Chaque Service LoadBalancer coûte en général une IP publique et un répartiteur facturé : on n'en met pas un par application.
ExternalName
spec:
type: ExternalName
externalName: bdd.prestataire.example.com
Les pods appellent bdd (un nom local) et le DNS du cluster répond par un alias vers le nom externe. Utile pour pouvoir changer de fournisseur sans toucher aux applications.
Headless (clusterIP: None)
Pas d'IP virtuelle : le nom DNS du Service renvoie directement les IP des pods. On l'utilise pour les StatefulSets (chaque pod a son nom DNS stable : base-0.base) et pour les clients qui veulent choisir eux-mêmes le pod à joindre (leçon 3.4).
2. Sous le capot
- Les EndpointSlices listent les pods prêts derrière chaque Service. Elles sont tenues à jour par un contrôleur du plan de contrôle.
- kube-proxy, sur chaque nœud, traduit les ClusterIP et NodePorts en règles du noyau (iptables, IPVS ou nftables) qui redirigent vers un pod des EndpointSlices. Certains plugins réseau (Cilium) le remplacent par des programmes eBPF.
- Une ClusterIP n'est attachée à aucune interface : on ne la « pingue » pas, elle n'existe que dans ces règles de traduction.
kubectl get endpointslices -l kubernetes.io/service-name=web -o wide
Un Service sans sélecteur n'a pas d'EndpointSlices automatiques : on peut les écrire à la main pour pointer vers des serveurs hors du cluster.
3. Et le web ? L'Ingress
Pour des sites et des API HTTP(S), un LoadBalancer par application coûte cher et ne sait rien faire du protocole web. On installe plutôt un seul point d'entrée, l'Ingress controller (Traefik, NGINX, HAProxy…), exposé une seule fois, puis on déclare des Ingress qui routent selon le nom de domaine et le chemin :
┌─ boutique.example.com/ ──► Service front
Internet ──► Ingress ──┼─ boutique.example.com/api ──► Service api
(1 IP) └─ admin.example.com ──► Service admin
L'Ingress gère aussi la terminaison TLS (certificats HTTPS, leçon 6.6). La Gateway API est son successeur, plus expressif (leçon 3.7).
4. Choisir
| Besoin | Choix |
|---|---|
| Une application appelée par d'autres applications du cluster | ClusterIP |
| Un test rapide depuis votre poste | kubectl port-forward |
| Un site ou une API HTTP(S) publique | Ingress (ou Gateway API) devant des ClusterIP |
| Un protocole non HTTP exposé à l'extérieur (base de données, MQTT, jeu…) | LoadBalancer |
| Un nom stable vers un service externe | ExternalName |
| Un pod précis d'un StatefulSet | Service headless |
Cette leçon se valide par le QCM de passage.