Équilibrage de charge dynamique A/B pour plusieurs clusters Kubernetes et contrôles de sécurité avec NGINX Plus

NGINX | 15 février 2024

Vous êtes ingénieur Platform Ops ou DevOps moderne. Vous utilisez un ensemble d’outils open source (et peut-être quelques outils commerciaux) pour tester, déployer et gérer de nouvelles applications et de nouveaux conteneurs pour votre équipe de développement. Vous avez choisi Kubernetes pour exécuter ces conteneurs et pods dans des environnements de développement, de test, de préproduction et de production. Vous avez adopté les architectures et les concepts des microservices et, dans l’ensemble, cela fonctionne plutôt bien. Cependant, vous avez rencontré quelques obstacles en cours de route.

Par exemple, lorsque vous créez et déployez de nouveaux clusters, services et applications, comment pouvez-vous facilement intégrer ou migrer ces nouvelles ressources en production sans interrompre le trafic ? Les équipements réseau traditionnels nécessitent un rechargement ou un redémarrage lors de la modification de la configuration des enregistrements DNS, des équilibreurs de charge, des pare-feu et des proxys. Ces paramètres ne peuvent pas être reconfigurés sans provoquer d’interruption, car une « interruption de service » ou une « fenêtre de maintenance » est nécessaire pour mettre à jour les règles DNS, des équilibreurs de charge et des pare-feu. Le plus souvent, vous devez soumettre un redoutable ticket d’assistance, puis attendre qu’une autre équipe approuve et effectue les modifications.

Les fenêtres de maintenance peuvent mener votre équipe dans une impasse, retarder la livraison des applications et vous faire dire : « Il doit bien y avoir une meilleure façon de gérer le trafic ! » Explorons donc une solution qui vous permettra de reprendre la voie rapide.

Équilibrage de charge multicluster actif-actif

Si vous disposez de plusieurs clusters Kubernetes, l’idéal est d’acheminer le trafic vers tous les clusters simultanément. Une option encore plus intéressante consiste à répartir le trafic selon une stratégie A/B, canary ou blue-green, et à envoyer un faible pourcentage de votre trafic à des fins de test. Pour ce faire, vous pouvez utiliser NGINX Plus avec ngx_http_split_clients_module.

Schéma de K8s avec NGINX Plus

Le module HTTP Split Clients est développé par NGINX Open Source et permet de répartir les requêtes selon un ratio défini à partir d’une clé. Dans ce cas d’utilisation, les clusters sont les « upstreams » de NGINX. Ainsi, à mesure que les requêtes clientes arrivent, le trafic est réparti entre deux clusters. La clé utilisée pour déterminer le traitement de la requête cliente peut être n’importe quelle $variable client NGINX disponible. Cela dit, pour contrôler cette répartition pour chaque requête, utilisez la variable $request_id, qui est un numéro unique attribué par NGINX à chaque requête entrante.

Pour configurer les ratios de répartition, déterminez le pourcentage de trafic que vous souhaitez envoyer à chaque cluster. Dans cet exemple, nous utilisons K8s Cluster1 comme « grand cluster » pour la production et Cluster2 comme « petit cluster » pour les tests de préproduction. Si vous disposiez d’un petit cluster pour l’environnement de staging, vous pourriez utiliser un ratio de 90:10 et tester 10 % de votre trafic sur le petit cluster afin de vous assurer que tout fonctionne avant de déployer les nouvelles modifications sur le grand cluster. Si cela vous semble trop risqué, vous pouvez passer à un ratio de 95:5. En réalité, vous pouvez choisir le ratio de votre choix, de 0 à 100 %.

Pour la plupart des trafics de production en temps réel, vous opterez probablement pour une répartition 50:50, avec deux clusters de taille égale. Mais vous pouvez facilement définir d’autres ratios en fonction de la taille des clusters ou d’autres paramètres. Vous pouvez aisément régler le ratio sur 0:100 (ou 100:0) afin de mettre à niveau, d’appliquer des correctifs, de réparer, voire de remplacer un cluster entier sans aucune interruption de service. Laissez NGINX split_clients acheminer les requêtes vers le cluster actif pendant que vous résolvez les problèmes sur l’autre.

# Nginx Multi Cluster Load Balancing
# HTTP Split Clients Configuration for Cluster1:Cluster2 ratios
# Provide 100, 99, 50, 1, 0% ratios  (add/change as needed)
# Based on
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – Jan 2024
#
 
split_clients $request_id $split100 {
   * cluster1-cafe;                     # All traffic to cluster1
   } 

split_clients $request_id $split99 {
   99% cluster1-cafe;                   # 99% cluster1, 1% cluster2
   * cluster2-cafe;
   } 
 
split_clients $request_id $split50 { 
   50% cluster1-cafe;                   # 50% cluster1, 50% cluster2
   * cluster2-cafe;
   }
    
split_clients $request_id $split1 { 
   1.0% cluster1-cafe;                  # 1% to cluster1, 99% to cluster2
   * cluster2-cafe;
   }

split_clients $request_id $split0 { 
   * cluster2-cafe;                     # All traffic to cluster2
   }
 
# Choose which cluster upstream based on the ratio
 
map $split_level $upstream { 
   100 $split100; 
   99 $split99; 
   50 $split50; 
   1.0 $split1; 
   0 $split0;
   default $split50;
}

Vous pouvez ajouter ou modifier la configuration ci-dessus afin qu’elle corresponde aux ratios dont vous avez besoin (par exemple, 90:10, 80:20, 60:40, etc.).

Remarque : NGINX dispose également d’un module Split Clients pour les connexions TCP dans le contexte stream, qui peut être utilisé pour le trafic non HTTP. Le trafic est alors réparti en fonction des nouvelles connexions TCP plutôt que des requêtes HTTP.

Magasin clé-valeur NGINX Plus

La fonctionnalité suivante que vous pouvez utiliser est le magasin clé-valeur de NGINX Plus. Il s’agit d’un objet clé-valeur situé dans une zone de mémoire partagée de NGINX, qui peut être utilisé dans de nombreux cas nécessitant le stockage de données. Ici, nous l’utilisons pour stocker la valeur du ratio de répartition mentionnée dans la section précédente. NGINX Plus vous permet de modifier n’importe quel enregistrement clé-valeur sans recharger NGINX. Vous pouvez ainsi modifier cette valeur de répartition à l’aide d’un appel d’API et créer une fonction de répartition dynamique.

Dans notre exemple, cela se présente comme suit :

{“cafe.example.com”:90}

Cet enregistrement KeyVal se lit comme suit :
La clé correspond au nom d’hôte « cafe.example.com »
La valeur « 90 » correspond au ratio de répartition

Au lieu de coder en dur le ratio de répartition dans les fichiers de configuration NGINX, vous pouvez utiliser la mémoire clé-valeur. Cela évite de devoir recharger NGINX pour modifier une valeur de répartition statique.

Dans cet exemple, NGINX est configuré pour utiliser un ratio de répartition de 90:10, avec le grand cluster Cluster1 pour les 90 % et le petit cluster Cluster2 pour les 10 % restants. Comme il s’agit d’un enregistrement clé-valeur, vous pouvez modifier ce ratio à l’aide de l’API NGINX Plus de manière dynamique, sans recharger la configuration ! Le module Split Clients utilisera cette nouvelle valeur de ratio dès que vous la modifierez, et ce, dès la requête suivante.

Créez l’enregistrement clé-valeur en commençant par une répartition 50/50 :

Ajoutez un nouvel enregistrement au magasin KeyValue en envoyant une commande API à NGINX Plus :

curl -iX POST -d '{"cafe.example.com":50}' http://nginxlb:9000/api/8/http/keyvals/split

Modifiez l’enregistrement KV pour passer à une répartition 90/10 :

Modifiez le ratio de répartition KeyVal à 90 à l’aide d’une méthode HTTP PATCH afin de mettre à jour l’enregistrement KeyVal en mémoire :

curl -iX PATCH -d '{"cafe.example.com":90}' http://nginxlb:9000/api/8/http/keyvals/split

Ensuite, l’équipe chargée des tests de préproduction vérifie que le nouveau code de l’application est prêt. Vous le déployez sur le grand cluster Cluster1 et faites passer la répartition à 100 %. Tout le trafic est alors immédiatement envoyé vers Cluster1, et votre nouvelle application est mise en production sans aucune interruption du trafic, indisponibilité de service, fenêtre de maintenance, redémarrage, rechargement ni multitude de tickets. Un seul appel d’API suffit pour modifier cette répartition au moment de votre choix.

Bien entendu, puisqu’il est si facile de passer de 90 % à 100 %, vous pouvez tout aussi aisément faire passer la répartition de 100:0 à 50:50 (voire à 0:100). Vous pouvez ainsi disposer d’un cluster de secours opérationnel ou faire évoluer horizontalement vos clusters en ajoutant de nouvelles ressources. Vous pouvez même aller jusqu’à créer intégralement un nouveau cluster doté des logiciels et du matériel les plus récents, ainsi que des derniers correctifs logiciels, puis déployer l’application et migrer progressivement le trafic sans interrompre la moindre connexion !

Cas d’usage

L’utilisation du module HTTP « Split Clients » avec le magasin clé-valeur dynamique permet de répondre aux cas d’usage suivants :

  • Équilibrage de charge actif-actif – Pour répartir la charge entre plusieurs clusters.
  • Équilibrage de charge actif-passif – Pour répartir la charge entre les clusters et applications principaux, de secours et de reprise après sinistre.
  • Tests A/B, blue-green et canary – Utilisés avec les nouvelles applications Kubernetes.
  • Mise à l’échelle horizontale du cluster – Ajoute des ressources au cluster et modifie le ratio lorsque vous êtes prêt.
  • Mises à niveau des clusters sans interruption – Possibilité d’utiliser un cluster pendant la mise à niveau, l’application de correctifs ou la réparation de l’autre cluster.
  • Basculement instant – Si l’un des clusters rencontre un problème grave, vous pouvez modifier le ratio afin d’utiliser l’autre cluster.

Exemples de configuration

Voici un exemple de configuration clé-valeur :

# Define Key Value store, backup state file, timeout, and enable sync 
keyval_zone zone=split:1m state=/var/lib/nginx/state/split.keyval timeout=365d sync;

keyval $host $split_level zone=split;

Et voici un exemple de configuration de l’application cafe.example.com :

# Define server and location blocks for cafe.example.com, with TLS
server {
   listen 443 ssl;
   server_name cafe.example.com; 

   status_zone https://cafe.example.com;
      
   ssl_certificate /etc/ssl/nginx/cafe.example.com.crt; 
   ssl_certificate_key /etc/ssl/nginx/cafe.example.com.key;
   
   location / {
   status_zone /;
   
   proxy_set_header Host $host;
   proxy_http_version 1.1;
   proxy_set_header "Connection" "";
   proxy_pass https://$upstream;   # traffic split to upstream blocks
   
   }

# Define 2 upstream blocks – one for each cluster
# Servers managed dynamically by NLK, state file backup

# Cluster1 upstreams
 
upstream cluster1-cafe {
   zone cluster1-cafe 256k;
   least_time last_byte;
   keepalive 16;
   #servers managed by NLK Controller
   state /var/lib/nginx/state/cluster1-cafe.state; 
}
 
# Cluster2 upstreams
 
upstream cluster2-cafe {
   zone cluster2-cafe 256k;
   least_time last_byte;
   keepalive 16;
   #servers managed by NLK Controller
   state /var/lib/nginx/state/cluster2-cafe.state; 
}

Les adresses IP et ports des serveurs en amont sont gérés par NGINX Loadbalancer for Kubernetes, un nouveau contrôleur qui utilise également l’API NGINX Plus pour configurer dynamiquement NGINX Plus. Vous trouverez plus d’informations dans la section suivante.

Examinons l’évolution dans le temps de la répartition du trafic HTTP avec Grafana, un outil populaire de surveillance et de visualisation. Vous utilisez NGINX Prometheus Exporter (basé sur njs) pour exporter toutes vos métriques NGINX Plus, qui sont ensuite collectées et représentées graphiquement par Grafana. Vous trouverez des informations détaillées sur la configuration de Prometheus et de Grafana ici.

Le graphique présente quatre serveurs en amont : deux pour Cluster1 et deux pour Cluster2. Nous utilisons un outil de génération de charge HTTP pour créer des requêtes HTTP et les envoyer à NGINX Plus.

Dans les trois graphiques ci-dessous, vous pouvez constater qu’au début, la répartition est de 50/50.

Schéma des requêtes en amont du LB

Ensuite, le ratio passe à 10:90 à 12:56:30.

Schéma des requêtes en amont du répartiteur de charge

Puis, la répartition passe à 90:10 à 13:00:00.

Schéma des requêtes en amont du répartiteur de charge

Vous trouverez des configurations fonctionnelles de Prometheus et Grafana dans le dépôt GitHub NGINX Loadbalancer for Kubernetes.

Groupes de serveurs HTTP dynamiques en amont : équilibreur de charge NGINX pour Kubernetes

Vous pouvez remplacer la configuration statique des groupes de serveurs NGINX par des groupes de serveurs de cluster dynamiques à l’aide de l’API NGINX Plus et du contrôleur NGINX Loadbalancer for Kubernetes. Ce projet gratuit est un contrôleur Kubernetes qui surveille NGINX Ingress Controller et met automatiquement à jour une instance externe de NGINX Plus configurée pour l’équilibrage de charge TCP/HTTP. Sa conception est très simple, tout comme son installation et son exploitation. Grâce à cette solution, vous pouvez mettre en œuvre l’équilibrage de charge TCP/HTTP dans les environnements Kubernetes, afin que les nouvelles applications et les nouveaux services soient immédiatement détectés et puissent recevoir du trafic, sans aucun rechargement.

Architecture et flux

NGINX Loadbalancer for Kubernetes s’exécute au sein d’un cluster Kubernetes. Il est enregistré auprès de Kubernetes pour surveiller le service NGINX Ingress Controller (nginx-ingress). Lorsqu’une modification est apportée au(x) contrôleur(s) Ingress, NGINX Loadbalancer for Kubernetes collecte les adresses IP des nœuds Worker et les numéros de ports TCP NodePort, puis envoie les paires IP:port à NGINX Plus via l’API NGINX Plus.

Les serveurs en amont NGINX sont mis à jour sans qu’aucun rechargement ne soit nécessaire, et NGINX Plus répartit le trafic entre les serveurs en amont et les NodePorts Kubernetes appropriés. Des instances NGINX Plus supplémentaires peuvent être ajoutées pour assurer une haute disponibilité.

Schéma du répartiteur de charge NGINX en fonctionnement

Aperçu du répartiteur de charge NGINX pour Kubernetes en action

Dans la capture d’écran ci-dessous, deux fenêtres montrent NGINX Loadbalancer for Kubernetes déployé et en fonctionnement :

  1. Type de service – LoadBalancer pour nginx-ingress
  2. IP externe – Se connecte aux serveurs NGINX Plus
  3. Ports – NodePort associe le port 443 au port 30158, avec les serveurs NGINX en amont correspondants (comme indiqué dans le tableau de bord en temps réel)
  4. Journaux – Indique que l’équilibreur de charge NGINX pour Kubernetes envoie correctement des données à NGINX Plus

Fenêtre NGINX Plus

Remarque : dans cet exemple, les nœuds de travail Kubernetes sont 10.1.1.8 et 10.1.1.10

Ajout de fonctionnalités de sécurité NGINX Plus

À mesure que de plus en plus d’applications exécutées dans Kubernetes sont exposées à l’Internet public, la sécurité devient indispensable. Heureusement, NGINX Plus offre des fonctionnalités de sécurité de niveau entreprise qui permettent de créer une architecture de défense en profondeur à plusieurs niveaux.

Avec NGINX Plus placé devant vos clusters et exécutant la fonction « split_clients », pourquoi ne pas tirer parti de sa présence pour ajouter des fonctionnalités de sécurité utiles ? Voici quelques-unes des fonctionnalités de NGINX Plus qui pourraient être utilisées pour renforcer la sécurité, ainsi que des liens et des références vers d’autres documents permettant de les configurer, de les tester et de les déployer.

Commencez dès aujourd’hui

Si les problèmes de réseau à la périphérie de votre cluster Kubernetes vous agacent, essayez cette solution multicluster NGINX. Testez le logiciel NGINX Loadbalancer for Kubernetes et dites-nous ce que vous en pensez. Le code source est disponible en open source (sous licence Apache 2.0) et toutes les instructions d’installation sont disponibles sur GitHub.

Pour nous faire part de vos commentaires, laissez-nous un message dans le dépôt ou contactez-nous sur le Slack de la communauté NGINX.


Partager

Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
NGINX | 13/10/2025

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA

Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
NGINX | 03/11/2023

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?

Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
NGINX | 11/03/2020

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX

Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
NGINX | 11/06/2019

Un testeur d’expressions régulières pour NGINX et NGINX Plus

Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.

Caches partagés avec les clusters de cache NGINX Plus, partie 1
NGINX | 24/01/2017

Caches partagés avec les clusters de cache NGINX Plus, partie 1

Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.

Introduction aux microservices
NGINX | 19/05/2015

Introduction aux microservices

Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.