Pour exposer des services au sein d'un cluster Kubernetes, deux mécanismes principaux de répartition de charge sont mis à disposition. Le premier s'appuie sur la ressource Service, opérant au niveau de la couche de transport (Layer 4 - TCP/UDP). Le second repose sur l'objet Ingress, qui intervient au niveau de la couche applicative (Layer 7 - HTTP/HTTPS).
Comparaison entre l'équilibrage de charge L4 et L7
Équilibrage au niveau Transport (L4) :
Qu'il utilise iptables ou ipvs, le service Kubernetes gère les flux via netfilter dans le noyau Linux. C'est une méthode générique capable de rediriger n'importe quel flux (HTTP, MySQL, etc.). Cependant, cette approche ne permet pas d'inspecter le contenu des paquets, empêchant ainsi le déchiffrement SSL ou le routage basé sur les URL. De plus, les mécanismes de vérification de l'état de santé (health checks) restent limités.
Équilibrage au niveau Applicatif (L7) :
Les ressources Ingress offrent une gestion plus fine du trafic. Elles permettent de définir des règles de routage complexes, telles que le mappage d'URL spécifiques ou la terminaison TLS. Contrairement au niveau 4, l'Ingress peut diriger le trafic vers différents services en fonction de l'hôte DNS ou du chemin d'accès (URI).
Comprendre l'Ingress et son Contrôleur
Par défaut, les adresses IP des Pods et des Services ne sont accessibles qu'à l'intérieur du réseau du cluster. Bien que le type NodePort ou LoadBalancer permette d'ouvrir des ports vers l'extérieur, cela reste une redirection brute de niveau 4.
L'objet Ingress est une collection de règles de routage. À lui seul, il n'est qu'une définition statique dans l'API Kubernetes. Pour que ces règles soient appliquées, un Contrôleur Ingress est nécessaire. Ce contrôleur est un Pod (souvent basé sur Nginx, Envoy, Traefik ou HAProxy) qui surveille l'API Kubernetes, détecte les ressources Ingress et configure son moteur de proxy interne pour diriger le trafic entrant directement vers les Pods cibles, court-circuitant souvent la latence du kube-proxy.
Structure d'une ressource Ingress
La configuration d'un Ingress repose sur des champs clés tels que rules, backend et tls. Voici un exemple de définition simple pour reidriger le domaine web.exemple.fr vers un service interne :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: routeur-principal
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: web.exemple.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-web-app
port:
number: 80
Dans cette configuration :
- rules : Définit la liste des règles de transfert basées sur l'hôte.
- backend : Spécifie le service cible par défaut si aucune règle n'est satisfaite.
- tls : Gère les certificats pour sécuriser les échanges via HTTPS.
Différents types de configuration Ingress
1. Exposition d'un service unique
Si vous souhaitez simplement exposer un service sans règles de domaine complexes, vous pouvez définir un defaultBackend.
spec:
defaultBackend:
service:
name: service-unique
port:
number: 8080
2. Routage basé sur les chemins d'URL
Utile pour les architectures micro-services où différentes parties d'un site sont gérées par des applications distinctes.
spec:
rules:
- host: api.entreprise.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1-service
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2-service
port:
number: 80
3. Hébergement virtuel basé sur le nom d'hôte
Permet de faire pointer plusieurs noms de domaine vers la même adresse IP du contrôleur, tout en les isolant logiciellement.
spec:
rules:
- host: boutique.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-boutique
port:
number: 80
- host: blog.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-blog
port:
number: 80
4. Terminaison TLS
L'Ingress permet de gérer le chiffrement SSL au niveau du point d'entrée, libérant ainsi les applications de cette charge.
spec:
tls:
- hosts:
- securise.exemple.com
secretName: cert-ssl-secret
rules:
- host: securise.exemple.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-interne
port:
number: 80
Mise en œuvre pratique avec Nginx Ingress Controller
Pour déployer une solution complète, nous allons suivre une approche par étapes : l'installation du contrôleur, la création de l'application et enfin la définition de la route.
Étape 1 : Installation du contrôleur
Le contrôleur Nginx est généralement déployé via un manifeste standard ou Helm. Il crée un Namespace dédié ingress-nginx et les ressources nécessaires (Deployments, ConfigMaps).
Étape 2 : Exposition du contrôleur
Pour que le trafic extérieur atteigne le contrôleur, on utilise souvent un service de type NodePort.
apiVersion: v1
kind: Service
metadata:
name: entree-nginx
namespace: ingress-nginx
spec:
type: NodePort
selector:
app.kubernetes.io/name: ingress-nginx
ports:
- name: http
port: 80
targetPort: 80
nodePort: 31080
- name: https
port: 443
targetPort: 443
nodePort: 31443
Étape 3 : Déploiement d'une application de test
Ici, nous déployons un serveur Java léger pour valider notre configuration.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-java-deploy
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: java-web
template:
metadata:
labels:
app: java-web
spec:
containers:
- name: java-runtime
image: openjdk:11-jre-slim
ports:
- containerPort: 8080
Étape 4 : Création du service et de la règle Ingress
Enfin, nous lions l'application au contrôleur via une règle Ingress DNS.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-java
namespace: production
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: java-app.cluster.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-java-backend
port:
number: 80
Une fois ces éléments déployés, toute requête arrivant sur un nœud du cluster sur le port 31080 avec l'entête Host java-app.cluster.local sera automatiquement redirigée vers les pods de l'application Java.