Ce tutoriel est l’un des quatre qui mettent en pratique les concepts abordés dans « Microservices de mars 2022 : mise en réseau Kubernetes » :
- Réduire la latence de Kubernetes grâce à la mise à l’échelle automatique
- Protégez les API Kubernetes grâce à la limitation du débit
- Protéger les applications Kubernetes contre les injections SQL (cet article)
- Améliorez la disponibilité et la résilience grâce à un déploiement Canary
Vous souhaitez obtenir des conseils détaillés sur l’utilisation de NGINX pour encore plus de cas d’usage réseau avec Kubernetes ? Téléchargez gratuitement notre e-book, « Gestion du trafic Kubernetes avec NGINX : guide pratique ».
Vous travaillez au service informatique d’un magasin local très fréquenté qui vend toutes sortes de produits, des oreillers aux vélos. L’enseigne s’apprête à lancer sa première boutique en ligne, mais elle a demandé à un expert en sécurité de réaliser un test d’intrusion du site avant sa mise en ligne. Malheureusement, l’expert en sécurité a découvert un problème ! La boutique en ligne est vulnérable à une injection SQL. L’expert en sécurité a pu exploiter cette faille pour obtenir des informations sensibles dans votre base de données, notamment des noms d’utilisateur et des mots de passe.
Votre équipe s’est tournée vers vous, l’ingénieur Kubernetes, pour sauver la situation. Heureusement, vous savez que l’injection SQL, comme d’autres vulnérabilités, peut être atténuée à l’aide des outils de gestion du trafic de Kubernetes. Vous avez déjà déployé un contrôleur Ingress pour rendre l’application accessible et, grâce à une seule configuration, vous pouvez empêcher l’exploitation de cette vulnérabilité. La boutique en ligne peut désormais être lancée dans les délais. Bravo !
Présentation du lab et du tutoriel
Ce blog accompagne le TP de l’unité 3 de Microservices March 2022 – « Modèle de sécurité des microservices dans Kubernetes » et montre comment utiliser NGINX et NGINX Ingress Controller pour bloquer les injections SQL.
Pour suivre ce tutoriel, vous avez besoin d’une machine disposant des éléments suivants :
- 2 processeurs ou plus
- 2 Go de mémoire disponible
- 20 Go d’espace disque disponible
- Connexion Internet
- Gestionnaire de conteneurs ou de machines virtuelles, tel que Docker, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox ou VMware Fusion/Workstation
- minikube installé
- Helm installé
- Une configuration permettant d’ouvrir une fenêtre de navigateur. Si ce n’est pas possible, vous devez déterminer comment accéder aux services concernés depuis un navigateur.
Pour tirer le meilleur parti du laboratoire et du tutoriel, nous vous recommandons, avant de commencer, de :
- Regardez l’enregistrement de la présentation conceptuelle diffusée en direct
- Consultez les articles de blog, le webinaire et la vidéo de présentation
- Regardez la vidéo de 16 minutes qui résume le laboratoire :
 
Ce tutoriel utilise les technologies suivantes :
- NGINX Open Source
- Contrôleur Ingress NGINX (basé sur NGINX Open Source)
- BusyBox
- Helm
- minikube
- Une application simple présentant des failles de sécurité, développée pour ce lab
Les instructions de chaque défi comprennent le texte intégral des fichiers YAML utilisés pour configurer les applications. Vous pouvez également copier ce texte depuis notre dépôt GitHub. Un lien vers GitHub est fourni avec le texte de chaque fichier YAML.
Ce tutoriel comprend quatre défis :
- Déployer un cluster et une application vulnérable
- Pirater l’application
- Utiliser un conteneur side-car NGINX pour bloquer certaines requêtes
- Configurer le contrôleur Ingress NGINX pour filtrer les requêtes
Défi 1 : déployer un cluster et une application vulnérable
Dans ce défi, vous allez déployer un cluster minikube et installer Podinfo comme exemple d’application présentant des vulnérabilités de sécurité.
Créer un cluster Minikube
Déployez un cluster minikube. Après quelques secondes, un message confirme que le déploiement a réussi.
$ minikube start
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by defaultInstaller l’application vulnérable
Vous allez ici déployer une application d’e-commerce simple composée de deux microservices :
- Une base de données MariaDB
- Un microservice PHP qui se connecte à la base de données et récupère les données
Suivez les étapes suivantes :
- À l’aide de l’éditeur de texte de votre choix, créez un fichier YAML nommé « 1-app.yaml » avec le contenu suivant (ou copiez-le depuis GitHub).
apiVersion: apps/v1 kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: f5devcentral/microservicesmarch:1.0.3
ports:
- containerPort: 80
env:
- name: MYSQL_USER
value: dan
- name: MYSQL_PASSWORD
value: dan
- name: MYSQL_DATABASE
value: sqlitraining
- name: DATABASE_HOSTNAME
value: db.default.svc.cluster.local
---
apiVersion: v1
kind: Service
metadata:
name: app
spec:
ports:
- port: 80
targetPort: 80
nodePort: 30001
selector:
app: app
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
spec:
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: mariadb:10.3.32-focal
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: root
- name: MYSQL_USER
value: dan
- name: MYSQL_PASSWORD
value: dan
- name: MYSQL_DATABASE
value: sqlitraining
---
apiVersion: v1
kind: Service
metadata:
name: db
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: db - Déployez l’application et l’API :
$ kubectl apply -f 1-app.yaml deployment.apps/app created
service/app created
deployment.apps/db created
service/db created - Vérifiez que les pods Podinfo ont bien été déployés, comme l’indique la valeur «
Running» dans la colonne «STATUS». Leur déploiement complet peut prendre 30 à 40 secondes. Attendez donc que l’état des deux pods soit «Running» avant de passer à l’étape suivante (en exécutant de nouveau la commande si nécessaire).
$ kubectl get podsNAME READY STATUS RESTARTS AGE
app-d65d9b879-b65f2 1/1 Running 0 37s
db-7bbcdc75c-q2kt5 1/1 Running 0 37s - Ouvrez l’application dans votre navigateur :
$ minikube service app|-----------|------|-------------|--------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------|-------------|--------------|
| default | app | | No node port |
|-----------|------|-------------|--------------|
😿 service default/app has no node port
🏃 Starting tunnel for service app.
|-----------|------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------|-------------|------------------------|
| default | app | | http://127.0.0.1:55446 |
|-----------|------|-------------|------------------------|
🎉 Opening service default/app in default browser... Défi 2 : piratez l’application
L’application d’exemple est assez basique. Elle comprend une page d’accueil présentant une liste d’articles (par exemple, des oreillers), ainsi qu’un ensemble de pages produit contenant des informations telles qu’une description et le prix. Les données sont stockées dans la base de données MariaDB. Chaque fois qu’une page est demandée, une requête SQL est envoyée à la base de données.
- Pour la page d’accueil, tous les éléments de la base de données sont récupérés.
- Pour une page produit, l’élément est récupéré à partir de son identifiant.
Lorsque vous ouvrez la page produit des « oreillers », vous remarquerez peut-être que l’URL se termine par « /product/1 ». Le chiffre 1 correspond à l’identifiant du produit. Pour empêcher l’insertion directe de code malveillant dans la requête SQL, il est recommandé d’assainir les entrées utilisateur avant de transmettre les requêtes aux services backend. Mais que se passe-t-il si l’application n’est pas correctement configurée et que l’entrée n’est pas échappée avant d’être insérée dans la requête SQL envoyée à la base de données ?
Exploitation 1
Pour vérifier si l’application échappe correctement les données saisies, effectuez un test simple en remplaçant l’identifiant par un identifiant qui n’existe pas dans la base de données.
Remplacez manuellement le dernier élément de l’URL, à savoir 1, par -1. Le message d’erreur Invalid product id "-1" indique que l’identifiant du produit n’est pas échappé : la chaîne est directement insérée dans la requête. Ce n’est pas une bonne nouvelle, sauf si vous êtes un pirate informatique !

Supposons que la requête de base de données ressemble à ceci :
SELECT * FROM some_table WHERE id = "1"Pour exploiter la vulnérabilité due à l’absence d’échappement de l’entrée, remplacez 1 par -1" <malicious_query> -- // afin d’obtenir :
- Le guillemet (
") après-1termine la première requête. - Vous pouvez ajouter votre propre requête malveillante après le guillemet.
- La séquence «
--//» ignore le reste de la requête.
Ainsi, par exemple, si vous remplacez le dernier élément de l’URL par « ‑1" » ou « 1 -- // », la requête compilée est la suivante :
SELECT * FROM some_table WHERE id = "-1" OR 1 -- //"
--------------
^ injected ^ Cela sélectionne toutes les lignes de la base de données, ce qui est utile lors d’un piratage. Pour vérifier si c’est bien le cas, remplacez la fin de l’URL par ‑1". Le message d’erreur qui s’affiche alors vous fournit davantage d’informations utiles sur la base de données :
Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"-1""' at line 1 in /var/www/html/product.php:23 Stack trace: #0 /var/www/html/product.php(23): mysqli->query('SELECT * FROM p...') #1 {main} thrown in /var/www/html/product.php on line 23Vous pouvez maintenant commencer à manipuler le code injecté afin de tenter de trier les résultats de la base de données par ID :
-1" OR 1 ORDER BY id DESC -- //Le résultat est la page produit du dernier article de la base de données.
Exploitation 2
Forcer la base de données à trier les résultats est intéressant, mais pas particulièrement utile si votre objectif est de la pirater. Il est bien plus intéressant d’essayer d’en extraire les noms d’utilisateur et les mots de passe.
On peut raisonnablement supposer que la base de données contient une table d’utilisateurs avec des noms d’utilisateur et des mots de passe. Mais comment étendre votre accès de la table des produits à celle des utilisateurs ?
La solution consiste à injecter du code comme ceci :
-1" UNION SELECT * FROM users -- //où
‑1"force la première requête à renvoyer un ensemble vide.UNIONforce la fusion de deux tables de base de données – dans ce cas, products et users – ce qui vous permet d’obtenir des informations (des mots de passe) qui ne figurent pas dans la table d’origine (products).SELECT*FROMuserssélectionne toutes les lignes de la table users.- La séquence «
--//» ignore tout ce qui suit la requête malveillante.
Lorsque vous modifiez l’URL pour qu’elle se termine par le code injecté, un nouveau message d’erreur s’affiche :
Fatal error: Uncaught mysqli_sql_exception: The used SELECT statements have a different number of columns in /var/www/html/product.php:23 Stack trace: #0 /var/www/html/product.php(23): mysqli->query('SELECT * FROM p...') #1 {main} thrown in /var/www/html/product.php on line 23Ce message révèle que les tables products et users n’ont pas le même nombre de colonnes. L’instruction UNION ne peut donc pas être exécutée. Vous pouvez toutefois déterminer le nombre de colonnes par tâtonnements, en ajoutant une à une des colonnes (noms de champs) comme paramètres de l’instruction SELECT. Dans une table users, le nom de champ password est une hypothèse plausible. Essayez donc ceci :
# select 1 column-1" UNION SELECT password FROM users; -- //
# select 2 columns
-1" UNION SELECT password,password FROM users; -- //
# select 3 columns
-1" UNION SELECT password,password,password FROM users; -- /
# select 4 columns
-1" UNION SELECT password,password,password,password FROM users; -- //
# select 5 columns
-1" UNION SELECT password,password,password,password,password FROM users; -- //La dernière requête aboutit (ce qui vous indique que la table users comporte cinq colonnes) et vous voyez le mot de passe d’un utilisateur :

À ce stade, vous ne connaissez pas le nom d’utilisateur correspondant à ce mot de passe. Mais comme vous connaissez le nombre de colonnes de la table users, vous pouvez utiliser les mêmes types de requêtes que précédemment pour révéler cette information. Supposons que le champ concerné s’appelle username. Et il s’avère que c’est bien le cas : la requête suivante révèle à la fois le nom d’utilisateur et le mot de passe de la table users. Ce qui est une excellente nouvelle… sauf si cette application est hébergée sur votre infrastructure !
-1" UNION SELECT username,username,password,password,username FROM users where id=1 -- //
Défi 3 : utiliser un conteneur side-car NGINX pour bloquer certaines requêtes
Le développeur de l’application de boutique en ligne doit manifestement accorder davantage d’attention à la validation et au nettoyage des entrées utilisateur (par exemple en utilisant des requêtes paramétrées), mais en tant qu’ingénieur Kubernetes, vous pouvez également contribuer à prévenir les injections SQL en empêchant l’attaque d’atteindre l’application. Ainsi, la vulnérabilité de l’application est moins problématique.
Il existe de nombreuses façons de protéger vos applications. Pour la suite de cet atelier, nous nous concentrerons sur deux d’entre elles :
- Dans ce défi, vous injectez un conteneur side-car dans le pod afin de relayer tout le trafic et de refuser toute requête dont l’URL contient
UNION. Commencez par déployer NGINX Open Source en tant que side-car, puis vérifiez s’il filtre les requêtes malveillantes. Remarque : nous utilisons cette technique uniquement à des fins d’illustration. En pratique, déployer manuellement des proxys en tant que side-cars n’est pas la meilleure solution (nous y reviendrons plus tard). - Dans le défi 4, nous utilisons NGINX Ingress Controller pour filtrer tout le trafic entrant dans le cluster.
Déployer NGINX Open Source en tant que side-car
- Créez un fichier YAML nommé « 2-app-sidecar.yaml » avec le contenu suivant (ou copiez-le depuis GitHub). Voici les principaux éléments de la configuration :
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: f5devcentral/microservicesmarch:1.0.3
ports:
- containerPort: 80
env:
- name: MYSQL_USER
value: dan
- name: MYSQL_PASSWORD
value: dan
- name: MYSQL_DATABASE
value: sqlitraining
- name: DATABASE_HOSTNAME
value: db.default.svc.cluster.local
- name: proxy # <-- sidecar
image: "nginx"
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /etc/nginx
name: nginx-config
volumes:
- name: nginx-config
configMap:
name: sidecar
---
apiVersion: v1
kind: Service
metadata:
name: app
spec:
ports:
- port: 80
targetPort: 8080 # <-- the traffic is routed to the proxy
nodePort: 30001
selector:
app: app
type: NodePort
---
apiVersion: v1
kind: ConfigMap
metadata:
name: sidecar
data:
nginx.conf: |-
events {}
http {
server {
listen 8080 default_server;
listen [::]:8080 default_server;
location ~* "(\'|\")(.*)(drop|insert|md5|select|union)" {
deny all;
}
location / {
proxy_pass http://localhost:80/;
}
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
spec:
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: mariadb:10.3.32-focal
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: root
- name: MYSQL_USER
value: dan
- name: MYSQL_PASSWORD
value: dan
- name: MYSQL_DATABASE
value: sqlitraining
---
apiVersion: v1
kind: Service
metadata:
name: db
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: db- Un conteneur side-car exécutant NGINX Open Source est démarré sur le port 8080.
- NGINX transfère tout le trafic vers l’application.
- Toute requête contenant (entre autres chaînes de caractères)
SELECTouUNIONest refusée (voir le premier bloclocationdans la sectionConfigMap). - Le service de l’application achemine d’abord tout le trafic vers le conteneur NGINX.
- Déployez le side-car :
$ kubectl apply -f 2-app-sidecar.yaml deployment.apps/app configured
service/app configured
configmap/sidecar created
deployment.apps/db unchanged
service/db unchanged Tester le side-car en tant que filtre
Vérifiez que le side-car filtre bien le trafic en revenant dans l’application et en tentant à nouveau l’injection SQL. NGINX bloque la requête avant qu’elle n’atteigne l’application !
-1" UNION SELECT username,username,password,password,username FROM users where id=1 -- // 
Défi 4 : configurer le contrôleur Ingress NGINX pour filtrer les requêtes
Protéger votre application comme dans le défi 3 est une expérience pédagogique intéressante, mais nous ne le recommandons pas en production pour les raisons suivantes :
- Il ne s’agit pas d’une solution de sécurité complète.
- Cette solution n’est pas évolutive (vous ne pouvez pas facilement appliquer cette protection à plusieurs applications).
- Sa mise à jour est complexe et inefficace.
Une bien meilleure solution consiste à utiliser NGINX Ingress Controller pour étendre la même protection à toutes vos applications ! Les contrôleurs Ingress permettent de centraliser toutes sortes de fonctionnalités de sécurité, du blocage des requêtes, à la manière d’un pare-feu d’applications web (WAF), jusqu’à l’authentification et l’autorisation.

Dans ce défi, vous allez déployer NGINX Ingress Controller, configurer le routage du trafic et vérifier que le filtre bloque l’injection SQL.
Déployer NGINX Ingress Controller
Le moyen le plus rapide d’installer NGINX Ingress Controller est d’utiliser Helm.
- Ajoutez le dépôt NGINX à Helm :
$ helm repo add nginx-stable https://helm.nginx.com/stable - Téléchargez et installez le contrôleur basé sur NGINX Open Source : NGINX Ingress Controller, qui est maintenu par F5 NGINX. Notez le paramètre
enableSnippets=true: les snippets servent à configurer NGINX afin de bloquer l’injection SQL. La dernière ligne de sortie confirme que l’installation a réussi.
$ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30005 \ --set controller.enableSnippets=true
NAME: main
LAST DEPLOYED: Day Mon DD hh:mm:ss YYYY
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES: The NGINX Ingress Controller has been installed. - Vérifiez que le pod du contrôleur Ingress NGINX a bien été déployé, comme l’indique la valeur «
Running» dans la colonne «STATUS».
$ kubectl get pods NAME READY STATUS ...
main-nginx-ingress-779b74bb8b-mtdkr 1/1 Running ...
... RESTARTS AGE
... 0 18sAcheminez le trafic vers votre application
- Créez un fichier YAML nommé 3-ingress.yaml avec le contenu suivant (ou copiez-le depuis GitHub). Il définit le manifeste Ingress nécessaire pour acheminer le trafic vers l’application (sans passer cette fois par le proxy side-car). Notez le bloc
annotations:dans lequel un extrait est utilisé pour personnaliser la configuration du contrôleur Ingress NGINX avec le même bloclocationque dans la définition de la ConfigMap du défi 3 : il rejette toute requête contenant, entre autres chaînes de caractères,SELECTouUNION.
apiVersion: v1 kind: Service
metadata:
name: app-without-sidecar
spec:
ports:
- port: 80
targetPort: 80
selector:
app: app
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: entry
annotations:
nginx.org/server-snippets: |
location ~* "(\'|\")(.*)(drop|insert|md5|select|union)" {
deny all;
}
spec:
ingressClassName: nginx
rules:
- host: "example.com"
http:
paths:
- backend:
service:
name: app-without-sidecar
port:
number: 80
path: /
pathType: Prefix - Déployez la ressource Ingress :
$ kubectl apply -f 3-ingress.yaml service/app-without-sidecar created
ingress.networking.k8s.io/entry created Vérifier le fonctionnement du filtre
- Lancez un conteneur BusyBox temporaire afin d’envoyer une requête au pod du contrôleur Ingress NGINX avec le nom d’hôte approprié.
$ kubectl run -ti --rm=true busybox --image=busybox$ wget --header="Host: example.com" -qO- main-nginx-ingress
<!DOCTYPE html>
<html lang="en">
<head>
# ...- Tentez l’injection SQL. Le code d’état
403Interditconfirme que NGINX bloque l’attaque !
$ wget --header="Host: example.com" -qO- 'main-nginx-ingress/product/-1"%20UNION%20SELECT%20username,username,password,password,username%20FROM%20users%20where%2 0id=1%20--%20//'
wget: server returned error: HTTP/1.1 403 Forbidden Étapes suivantes
Kubernetes n’est pas sécurisé par défaut. Un contrôleur Ingress peut atténuer les vulnérabilités liées aux injections SQL (ainsi que de nombreuses autres vulnérabilités). Gardez toutefois à l’esprit que les fonctionnalités de type WAF que vous venez de mettre en œuvre avec NGINX Ingress Controller ne remplacent ni un véritable WAF ni une architecture sécurisée des applications. Un pirate expérimenté peut toujours faire fonctionner l’attaque UNION en apportant quelques petites modifications au code. Pour en savoir plus à ce sujet, consultez Guide des injections SQL (SQLi) à l’usage des pentesteurs.
Cela dit, un contrôleur Ingress reste un outil puissant pour centraliser l’essentiel de votre sécurité, ce qui permet d’améliorer l’efficacité et la sécurité, notamment grâce à la centralisation de l’authentification et des autorisations (mTLS, authentification unique), voire à l’utilisation d’un WAF robuste tel que F5 NGINX App Protect WAF.
La complexité de vos applications et de votre architecture peut nécessiter un contrôle plus granulaire. Si votre organisation exige une approche Zero Trust et un chiffrement de bout en bout, envisagez un maillage de services tel que F5 NGINX Service Mesh, qui est toujours gratuit, pour contrôler les communications entre les services du cluster Kubernetes (trafic est-ouest). Nous abordons les maillages de services dans l’unité 4, « Stratégies avancées de déploiement Kubernetes ».
Pour plus d’informations sur l’obtention et le déploiement de NGINX Open Source, consultez nginx.org.
Pour essayer le NGINX Ingress Controller basé sur NGINX Plus avec NGINX App Protect, commencez votre essai gratuit de 30 jours dès aujourd’hui ou contactez-nous pour discuter de vos cas d’utilisation.
Pour essayer le contrôleur Ingress NGINX basé sur NGINX Open Source, consultez les versions du contrôleur Ingress NGINX dans notre dépôt GitHub ou téléchargez un conteneur précompilé depuis DockerHub.
À propos de l’auteur
Articles de blog associés

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 ?
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
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
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
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
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.
