Comment simplifier la gestion du trafic entrant et sortant dans Kubernetes

NGINX | 28 juin 2021

L’une des situations dans lesquelles un maillage de services peut réellement compliquer la gestion d’un environnement Kubernetes est lorsqu’il doit être configuré séparément du contrôleur Ingress. Les configurations distinctes ne sont d’ailleurs pas seulement chronophages. Elles augmentent également le risque d’erreurs de configuration susceptibles d’empêcher le bon acheminement du trafic, voire d’entraîner des failles de sécurité (par exemple, permettre à des acteurs malveillants d’accéder à des applications restreintes) et une mauvaise expérience utilisateur (par exemple, empêcher des clients d’accéder aux applications pour lesquelles ils disposent d’une autorisation). Outre le temps nécessaire pour effectuer ces configurations séparées, vous finissez par consacrer davantage de temps à résoudre les erreurs.

Vous pouvez éviter ces problèmes – et gagner du temps – en intégrant le contrôleur Ingress NGINX basé sur NGINX Plus à NGINX Service Mesh afin de contrôler le trafic mTLS entrant et sortant. Dans cette démonstration vidéo, nous présentons toutes les étapes.

Les documents justificatifs sont mentionnés dans les sections suivantes :

Prérequis (0:18)

Avant de commencer la démonstration proprement dite, nous avons effectué les préparatifs suivants :

  1. Installation du plan de contrôle NGINX Server Mesh dans le cluster Kubernetes et configuration de mTLS et de la stratégie strict pour le maillage de services.
  2. Installation de NGINX Ingress Controller basé sur NGINX Plus en tant que déploiement (plutôt que DaemonSet) dans le cluster Kubernetes, activation du trafic sortant, puis exposition en tant que service de type LoadBalancer.Remarque : La démonstration ne fonctionne pas avec NGINX Ingress Controller basé sur NGINX Open Source. Pour faciliter la lecture, dans la suite de cet article, nous désignons simplement NGINX Ingress Controller basé sur NGINX Plus par « NGINX Ingress Controller ».
  3. Suivi nos instructions pour télécharger l’application d’exemple bookinfo, injecter le side-car NGINX Service Mesh et déployer l’application.

En raison de la stratégie strict créée à l’étape 1, les requêtes adressées à l’application bookinfo par des clients extérieurs au maillage sont refusées au niveau du side-car. Dans cette démonstration, nous l’illustrons en exécutant d’abord la commande suivante pour configurer la redirection de port :

> kubectl port-forward svc/product-page 9080Forwarding from 127.0.0.1:9080 -> 9080
Forwarding from [::1]:9080 -> 9080
Handling connection for 9080

Lorsque nous essayons d’accéder à l’application, nous obtenons le code d’état 503 car notre machine locale ne fait pas partie du maillage de services :

> curl localhost:9080503

Déploiement de NGINX Ingress Controller avec NGINX Service Mesh (1:50)

La première étape du processus d’exposition d’une application consiste à déployer une instance de NGINX Ingress Controller. Les instructions correspondantes sont fournies dans notre tutoriel, « Déployer avec NGINX Plus Ingress Controller pour Kubernetes ».

NGINX fournit à cet effet des manifestes Deployment et DaemonSet. Dans la démonstration, nous utilisons le manifeste Deployment, « nginx-plus-ingress.yaml ». Il comprend des annotations permettant d’acheminer le trafic entrant et sortant via la même instance de NGINX Ingress Controller :

Chargement de l’exemple de code…

Le manifeste permet l’intégration directe de NGINX Ingress Controller à Spire, l’autorité de certification (CA) de NGINX Service Mesh, ce qui évite d’avoir à injecter le conteneur side-car de NGINX Service Mesh dans NGINX Ingress Controller. À la place, NGINX Ingress Controller récupère directement les certificats et les clés auprès de l’autorité de certification Spire afin de les utiliser pour le protocole mTLS avec les pods du maillage. Le manifeste indique l’adresse de l’agent Spire :

Chargement de l’exemple de code…

et monte le socket UNIX de l’agent Spire dans le pod NGINX Ingress Controller :

Chargement de l’exemple de code…

Le dernier point à noter concernant le manifeste est l’argument de ligne de commande « -enable-internal-routes », qui nous permet d’acheminer le trafic vers les services de sortie :

Chargement de l’exemple de code…

Avant de commencer la démonstration, nous avons exécuté la commande « kubectl apply -f nginx-plus-ingress.yaml » pour installer NGINX Ingress Controller. À présent, nous examinons le déploiement dans l’espace de noms nginx-ingress. Comme l’indique la colonne READY de la sortie suivante, le pod NGINX Ingress Controller ne comporte qu’un seul conteneur, car nous n’y avons pas injecté de side-car NGINX Service Mesh.

Nous avons également déployé un service de type LoadBalancer afin d’exposer l’adresse IP externe du contrôleur Ingress NGINX (ici, 35.233.133.188) en dehors du cluster. Nous accéderons à l’application d’exemple bookinfo à cette adresse IP.

> kubectl get pods --namespace=nginx-ingressNAME                                 READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-867f954b8f0fzdrm   1/1     Running   0          3d3h

NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP      ...
service-nginx-ingress   LoadBalancer   10.31.245.207   35.233.133.188   ...

      ... PORT(S)                      AGE
      ... 80:31469/TCP,443:32481/TCP   4d2h
...

Utiliser une ressource Ingress Kubernetes standard pour exposer l’application (3:55)

Nous exposons maintenant l’application « bookinfo » dans le maillage à l’aide d’une ressource Ingress Kubernetes standard, telle que définie dans bookinfo-ingress.yaml. Les instructions correspondantes sont fournies dans notre tutoriel « Exposer une application avec NGINX Plus Ingress Controller ».

Chargement de l’exemple de code…

La ressource fait référence à un Secret Kubernetes pour l’application « bookinfo » à la ligne 10 et comprend une règle de routage qui indique que les requêtes adressées à bookinfo.example.com sont envoyées au service « productpage » (lignes 11 à 18). Le Secret est défini dans bookinfo-secret.yaml :

Chargement de l’exemple de code…

Nous exécutons cette commande pour charger la clé et le certificat, qui est autosigné dans cette démonstration :

> kubectl apply -f bookinfo-secret.yamlsecret/bookinfo-secret unchanged

Nous activons la ressource Ingress :

> kubectl apply -f bookinfo-ingress.yamlingress.networking.k8s.io/bookinfo-ingress deleted

et vérifiez que l’Ingress Controller a ajouté la route définie dans la ressource, comme le confirme l’événement à la fin de la sortie :

> kubectl describe ingress bookinfo-ingress...
Events:
  Type    Reason          Age   From                      Message
  ----    ------          ----  ----                      -------
  Normal  AddedOrUpdated  5s    nginx-ingress-controller  Configuration for ...
        ...default/bookinfo-ingress was added or updated

Dans la démonstration, nous utilisons maintenant un navigateur pour accéder à l’application bookinfo à l’adresse https://bookinfo.example.com/. (Nous avons préalablement ajouté, dans le fichier local /etc/hosts, une correspondance entre l’adresse IP du service Ingress Controller – 35.233.133.188 dans la démonstration, comme indiqué ci-dessus – et bookinfo.example.com. Pour obtenir des instructions, consultez la documentation.) Les informations de la section Avis sur les livres de la page changent régulièrement à mesure que les requêtes sont réparties entre les trois versions du service reviews définies dans bookinfo.yaml (télécharger).

Nous allons ensuite inspecter le trafic entrant dans les clusters. Nous exécutons le script generate-traffic.sh pour envoyer des requêtes au service productpage via l’adresse IP publique du contrôleur Ingress NGINX, puis nous exécutons la commande nginx-meshctl top pour surveiller le trafic :

> nginxmesh-ctl top deploy/productpage-v1Deployment       Direction  Resource       Success Rate  P99    P90    P50   ...
productpage-v1  
                 To         details-v1     100.00%       3ms    3ms    2ms   
                 To         reviews-v2     100.00%       99ms   90ms   20ms
                 To         reviews-v3     100.00%       99ms   85ms   18ms
                 To         reviews-v1     100.00%       20ms   17ms   9ms
                 From       nginx-ingress  100.00%       192ms  120ms  38ms

      ... NumRequests 
      ... 14
      ... 5
      ... 5
      ... 12

Utilisation d’une ressource VirtualServer NGINX pour exposer l’application (6:45)

Nous présentons ensuite une autre façon d’exposer une application à l’aide d’une ressource VirtualServer de NGINX. Il s’agit d’une ressource personnalisée du contrôleur Ingress NGINX qui prend en charge une gestion plus complexe du trafic, notamment la répartition du trafic et le routage basé sur le contenu.

Nous commençons par supprimer la ressource Ingress standard :

> kubectl delete -f bookinfo-ingress.yamlingress.networking.k8s.io "bookinfo-ingress" deleted

Notre fichier bookinfo-vs.yaml configure le mTLS avec le même Secret que dans bookinfo-ingress.yaml (lignes 7 à 8). Les lignes 9 à 12 définissent le service productpage comme serveur en amont, et les lignes 13 à 24 définissent une route qui envoie toutes les requêtes GET adressées à bookinfo.example.com vers ce serveur en amont. Pour les méthodes HTTP autres que GET, il renvoie le code d’état 405.

Chargement de l’exemple de code…

Nous appliquons la ressource :

> kubectl apply -f bookinfo-vs.yamlvirtualserver.kubernetes.nginx.org/bookinfo-vs created

Nous suivons ensuite les mêmes étapes que pour la ressource Ingress : nous exécutons la commande kubectl describe pour vérifier que le déploiement s’est correctement déroulé, puis nous accédons à l’application dans un navigateur. Le rejet de la méthode POST confirme également que l’application fonctionne correctement :

> curl -k -X POST https://bookinfo.example.com/Method not allowed

Configuration d’une route de sortie sécurisée avec NGINX Ingress Controller (8:44)

Nous allons maintenant vous montrer comment acheminer le trafic sortant via NGINX Ingress Controller. Notre tutoriel « Configurer une route de sortie sécurisée avec NGINX Plus Ingress Controller » décrit la procédure à l’aide de différents exemples d’applications.

Nous avons déjà défini un pod bash simple dans bash.yaml et l’avons déployé dans l’espace de noms par défaut, depuis lequel nous envoyons des requêtes. Comme l’indique la colonne READY de cette sortie, le side-car NGINX Service Mesh y a été injecté.

> kubectl get allNAME                        READY  STATUS    RESTARTS   AGE
pod/bash-6ccb678958-zsgm7   2/2    Running   0          77s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.31.240.1   <none>        443/TCP   4d2h
...

Dans plusieurs cas d’usage, vous pouvez souhaiter autoriser les requêtes provenant du pod vers un service de sortie, c’est-à-dire toute entité ne faisant pas partie de NGINX Service Mesh. Il peut s’agir, par exemple, de services déployés :

  • En dehors du cluster
  • Sur un autre cluster
  • Sur le même cluster, mais sans injection du side-car NGINX Service Mesh

Dans la démonstration, nous examinons le dernier cas d’utilisation. Une application est déployée dans l’espace de noms legacy, qui n’est pas géré par NGINX Service Mesh et dans lequel l’injection automatique du side-car NGINX Service Mesh est désactivée. Un seul pod exécute l’application.

> kubectl get all --namespaces=legacyNAME                          READY  STATUS    RESTARTS   AGE
pod/target-5f7bcb96c6-km9lz   1/1    Running   0          27m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/target-svc   ClusterIP   10.31.245.213   <none>        80/TCP,443/TCP   27m
...

Rappelez-vous que nous avons configuré une politique mTLS strict pour NGINX Service Mesh. Par conséquent, nous ne pouvons pas envoyer de requêtes directement depuis le pod bash vers le service cible, car ils ne peuvent pas s’authentifier mutuellement. Lorsque nous essayons, nous obtenons le code d’état 503, comme illustré ici :

> kubectl exec -it bash-6ccb678958-zsgm7 -c bash -- curl target-svc.legacycurl: (56) Recv failure: connection reset by peer
503command terminated with exit code 56

La solution consiste à permettre au pod bash d’envoyer le trafic sortant via NGINX Ingress Controller. Nous décommentons l’annotation aux lignes 14 et 15 de bash.yaml :

Chargement de l’exemple de code…

Nous appliquons ensuite la nouvelle configuration :

> kubectl apply -f bash.yamldeployment.apps/bash configured

et vérifiez qu’un nouveau pod bash a bien démarré :

> kubectl get podsNAME                    READY  STATUS        RESTARTS   AGE
bash-678c8b4579-7sfml   2/2    Running       0          6s
bash-6ccb678958-zsgm7   2/2    Terminating   0          3m28s

Désormais, lorsque nous exécutons la même commande kubectl exec que précédemment pour envoyer une requête du pod bash au service cible, nous obtenons le code d’état 404 au lieu de 503. Cela indique que le pod bash a bien envoyé la requête à NGINX Ingress Controller, mais que ce dernier ne sait pas où la transférer, car aucune route n’est définie.

Nous créons la route requise à l’aide de la définition de ressource Ingress suivante dans legacy-route.yaml. L’annotation internal-route à la ligne 7 signifie que le service cible n’est pas exposé à Internet, mais uniquement aux charges de travail au sein de NGINX Service Mesh.

Chargement de l’exemple de code…

Nous activons la nouvelle ressource et vérifions que NGINX Ingress Controller a ajouté la route définie dans celle-ci :

> kubectl apply -f legacy-route.yamlingress.networking.k8s.io/target-internal-route created
> kubectl describe ingress target-internal-route -n legacy
...
Events:
  Type    Reason          Age   From                      Message
  ----    ------          ----  ----                      -------
  Normal  AddedOrUpdated  6s    nginx-ingress-controller  Configuration for ...
        ...legacy/target-internal-route was added or updated

Désormais, lorsque nous exécutons la commande « kubectl exec », nous atteignons le service cible :

{"req": {"method": "GET"                "url": "/",
                "host": "target-svc.legacy",
                "remoteAddr": "10.28.2.76:56086"}}

L’un des avantages du routage du trafic sortant via NGINX Ingress Controller est que vous pouvez contrôler précisément les services externes accessibles depuis le cluster : seuls ceux pour lesquels vous définissez une route le sont.

Pour finir, nous montrons dans la démonstration comment surveiller le trafic sortant. Nous exécutons la commande kubectl exec pour envoyer plusieurs requêtes, puis nous exécutons la commande suivante :

> nginxmesh-ctl top deploy/nginx-ingress -n nginx-ingressDeployment      Direction  Resource  Success Rate  P99  P90  P50  NumRequests
nginx-ingress  
                To         target    100.00%       1ms  1ms  1ms  9
                From       bash      100.00%       0ms  0ms  0ms  9

Dites « non » à la latence – Essayez NGINX Service Mesh avec NGINX Ingress Controller

De nombreux maillages de services proposent des options de passerelle d’entrée et de sortie, mais l’intégration de NGINX offre un avantage supplémentaire que vous apprécierez : une latence réduite. La plupart des maillages nécessitent l’injection d’un side-car dans le contrôleur Ingress, ce qui impose au trafic un saut supplémentaire avant d’atteindre vos applications. Chaque seconde compte, et ce saut supplémentaire, qui ralentit vos expériences numériques, pourrait inciter vos clients à se tourner vers la concurrence. NGINX Service Mesh n’ajoute aucune latence inutile, car il n’injecte pas de side-car dans NGINX Ingress Controller. Au lieu de cela, grâce à une intégration directe avec Spire, l’autorité de certification du maillage, NGINX Ingress Controller devient partie intégrante de NGINX Service Mesh. NGINX Ingress Controller récupère simplement les certificats et les clés auprès de l’agent Spire et les utilise pour participer à l’échange de certificats mTLS avec les pods intégrés au maillage.

Il existe deux versions de NGINX Ingress Controller pour Kubernetes : NGINX Open Source et NGINX Plus. Pour déployer NGINX Ingress Controller avec NGINX Service Mesh comme décrit dans cet article de blog, vous devez utiliser la version NGINX Plus, qui est disponible dans le cadre d’un essai gratuit de 30 jours.

NGINX Service Mesh est entièrement gratuit et disponible en téléchargement immédiat. Il peut être déployé en moins de 10 minutes ! Pour commencer, consultez la documentation et faites-nous part de votre expérience sur GitHub.


Partager
Mots-clés : 2021, F5 NGINX, Tech

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.