Lorsqu’une entreprise déploie un cluster Kubernetes, elle a souvent déjà des reverse proxies en place pour gérer l’accès à ses services web, qu’ils soient publics ou internes (DMZ, PROD, QUALIF). L’enjeu est d’intégrer ces reverse proxies existants avec Kubernetes sans perturber les configurations actuelles, notamment en gardant les vhosts en place. Kubernetes sera utilisé comme solution de dernier recours, avec un default_server dans le reverse proxy pour rediriger vers un Ingress Controller en cas de service non trouvé.
Table of Contents
Reverse Proxy : Fonction et Rôle
Un reverse proxy est un intermédiaire qui redirige les requêtes entrantes vers les serveurs appropriés. Dans une architecture d’entreprise, les reverse proxies sont souvent configurés pour des environnements spécifiques :
- DMZ : Pour les services publics.
- PROD : Pour les applications internes critiques.
- QUALIF : Pour les environnements de test.
Les vhosts (virtual hosts) sont utilisés pour rediriger les requêtes basées sur des noms d’hôtes spécifiques vers les services backend correspondants.
Intégration de Kubernetes avec les Reverse Proxies
Garder les vhosts existants
Les reverse proxies actuels continueront de rediriger les requêtes vers les services définis via des vhosts configurés. Il est important de ne pas toucher à ces configurations pour garantir la continuité des services existants.
Utiliser Kubernetes comme « default_server »
Kubernetes est utilisé en dernier recours pour gérer les requêtes qui ne correspondent à aucun vhost. Cela signifie que si un reverse proxy ne trouve pas le service demandé, il redirige la requête vers le Ingress Controller de Kubernetes.
Exemple de Configuration NGINX
# Configuration NGINX avec les vhosts existants et Kubernetes en fallback
server {
listen 80;
server_name app.prod.example.com;
location / {
proxy_pass http://backend_prod;
}
}
server {
listen 80;
server_name app.dmz.example.com;
location / {
proxy_pass http://backend_dmz;
}
}
# Kubernetes en tant que default_server
server {
listen 80 default_server;
server_name _;
location / {
proxy_pass http://kubernetes_ingress_controller;
}
}
Note : Dans cette configuration de base, aucun mécanisme interne à NGINX n’est mis en place pour vérifier l’état des nœuds Kubernetes. Cela signifie que si le nœud vers lequel pointe kubernetes_ingress_controller
est indisponible, NGINX continuera tout de même à lui envoyer du trafic. Pour pallier ce problème, il est conseillé de mettre en œuvre un mécanisme de vérification de santé (checks passifs, checks actifs via un module tiers, utilisation d’un LoadBalancer externe, ou encore une IP virtuelle gérée par Keepalived au sein du cluster).
Gestion du SSL : Offloading ou Chiffrement de Bout en Bout
Dans de nombreuses architectures, il est courant que le reverse proxy gère le SSL (appelé SSL offloading). Cela signifie que le trafic entre le client et le reverse proxy est sécurisé via HTTPS, mais que les communications entre le reverse proxy et les services backend (ici, Kubernetes) se font en HTTP, généralement sur le port 80.
Scénario SSL Offloading :
- Client → Reverse Proxy : Le trafic est chiffré (HTTPS).
- Reverse Proxy → Kubernetes : Le trafic est redirigé en HTTP (port 80).
Cette approche simplifie la gestion des certificats SSL, car ils ne sont gérés qu’au niveau du reverse proxy. Cependant, l’idéal serait de chiffrer de bout en bout, c’est-à-dire :
- Client → Reverse Proxy : Trafic chiffré avec HTTPS.
- Reverse Proxy → Kubernetes : Trafic également chiffré avec HTTPS, jusqu’à l’Ingress Controller Kubernetes.
Cela garantit un niveau de sécurité maximal en évitant que les données soient transmises en clair, même dans les réseaux internes. Toutefois, pour les infrastructures où la gestion des certificats est centralisée, l’approche SSL offloading reste acceptable, tant que les réseaux internes sont bien sécurisés.
Surveillance et Sondes de Santé
Kubernetes est déjà configuré avec des probes (sondes de santé) pour surveiller les services déployés. Si un service dans Kubernetes rencontre un problème, il renverra une réponse 404, et le reverse proxy pourra afficher une page d’erreur globale préconfigurée. Il n’est donc pas nécessaire de configurer des sondes de santé supplémentaires au niveau du reverse proxy, car vos déploiements Kubernetes se doivent de déjà gérer ce mécanisme en interne.
Toutefois, un point important à considérer est la disponibilité des nœuds Kubernetes eux-mêmes. Si vous utilisez un fallback vers un Ingress Controller exposé via un NodePort, rien ne garantit que NGINX ne tombera pas sur un nœud hors service. Dans ce cas, vous risquez d’envoyer du trafic vers un nœud mort.
Approches pour Assurer la Disponibilité en Cas de Fallback
1. Utiliser un LoadBalancer (Cloud ou MetalLB)
Un Service de type LoadBalancer fournit une IP stable et des checks de santé en amont. Le load balancer distribue le trafic uniquement vers les nœuds sains. NGINX ne pointe alors que vers une seule IP fiable.
2. Mettre un Load Balancer dédié (HAProxy, NGINX, F5, etc.)
Un LB intermédiaire avec sondes de santé actives permet d’écarter les nœuds morts. NGINX pointe vers ce LB, qui ne redirige le trafic que vers des nœuds en bon état.
3. Checks passifs côté NGINX
La version Open Source de NGINX permet des checks passifs avec max_fails
et fail_timeout
. En cas d’erreurs répétées sur un nœud, celui-ci est marqué comme indisponible temporairement.
Exemple :
upstream kubernetes_ingress {
server node1.k8s.example.com:80 max_fails=3 fail_timeout=30s;
server node2.k8s.example.com:80 max_fails=3 fail_timeout=30s;
}
server {
listen 80 default_server;
server_name _;
location / {
proxy_pass http://kubernetes_ingress;
proxy_next_upstream error timeout http_502 http_503 http_504;
}
}
Ceci est simple et gratuit, mais non proactif.
4. Checks actifs avec un module tiers
En recompilant NGINX avec ngx_http_upstream_check_module
, vous pouvez mettre en place des checks actifs (pings réguliers sur /healthz
). Ainsi, NGINX exclut automatiquement les nœuds indisponibles. Cette solution est gratuite, mais plus technique (recompilation de NGINX).
5. Adresse IP virtuelle avec Keepalived sur les Masters (Control Plane)
Une autre solution consiste à mettre en place Keepalived sur les nœuds du control plane pour présenter une IP virtuelle hautement disponible. Keepalived utilise VRRP pour déterminer quel nœud master détient l’IP virtuelle à un instant donné. En cas de défaillance du nœud actif, l’IP bascule automatiquement vers un autre master disponible.
Ainsi, NGINX ne pointe que vers cette IP virtuelle unique. L’IP flotte entre les masters en fonction de leur disponibilité, garantissant qu’il y a toujours au moins un nœud sain derrière cette IP. Pas besoin de checks compliqués côté NGINX, c’est le mécanisme de failover de Keepalived qui assure la disponibilité en ne présentant qu’un seul endpoint à NGINX.
Avantages de cette Approche
- Compatibilité : Les vhosts existants ne sont pas modifiés.
- Évolutivité : Kubernetes peut être intégré progressivement sans perturber l’infrastructure.
- Simplicité : Kubernetes est utilisé uniquement en dernier recours, simplifiant la gestion des routes.
- Sécurité : L’approche SSL offloading est simple, mais un chiffrement de bout en bout peut être envisagé pour plus de sécurité.
Conclusion
L’intégration d’un cluster Kubernetes dans une entreprise ayant déjà des reverse proxies en place se fait facilement en conservant les vhosts existants et en utilisant Kubernetes comme default_server. Cela garantit une transition en douceur et permet à Kubernetes de gérer les services nouveaux ou migrés sans modifier l’infrastructure actuelle. Pour la gestion des certificats, le SSL offloading est pratique, mais le chiffrement de bout en bout est recommandé pour un maximum de sécurité.
Pour garantir une haute disponibilité, différentes options s’offrent à vous : LoadBalancer, checks passifs/actifs dans NGINX, ou encore une IP virtuelle gérée par Keepalived sur les masters. Le choix dépendra de votre contexte (Cloud, on-prem, outillage existant). Les sondes de santé de Kubernetes gèrent déjà la disponibilité des services, tandis que les mécanismes ci-dessus assurent la résilience des nœuds et du point d’entrée.