Gestion du trafic applicatif avec les ressources Ingress dans Kubernetes

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.

Étiquettes: kubernetes ingress nginx LoadBalancing devops

Publié le 1 juillet à 21h51