upstream-jdomain: Module de résolution de noms de domaine asynchrone pour NGINX upstream
Installation
Vous pouvez installer ce module dans n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :
- RedHat Enterprise Linux 7, 8, 9 et 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 et Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-upstream-jdomain
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-upstream-jdomain
Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :
load_module modules/ngx_http_upstream_jdomain_module.so;
Ce document décrit nginx-module-upstream-jdomain v1.5.2 publié le 09 décembre 2024.
Un module de résolution de noms de domaine asynchrone pour nginx upstream.
Ce module vous permet d'utiliser un nom de domaine dans un bloc upstream et de s'attendre à ce que le nom de domaine soit résolu dynamiquement afin que votre upstream puisse être résilient aux mises à jour des entrées DNS.
Le module ne réalise pas la résolution DNS automatiquement à intervalles réguliers. Au lieu de cela, la résolution DNS doit être déclenchée par une requête pour le upstream donné. Si nginx sert une connexion destinée à un upstream jdomain, et que l'interval configuré a expiré, alors le module effectuera une recherche DNS.
Le module est compatible avec d'autres directives de portée upstream. Cela signifie que vous pouvez remplir un bloc upstream avec plusieurs directives jdomain, plusieurs directives server, keepalive, directives de répartition de charge, etc. Notez que, à moins qu'une autre méthode de répartition de charge ne soit spécifiée dans le bloc upstream, ce module utilise l'algorithme de répartition de charge par défaut en round robin intégré au cœur de nginx.
Remarque importante : Si un algorithme de répartition de charge alternatif est spécifié, il doit venir avant la directive jdomain dans le bloc upstream ! Si cela n'est pas respecté, nginx va planter pendant l'exécution ! Cela est dû au fait que de nombreux autres modules de répartition de charge étendent explicitement le round robin intégré, et finissent donc par écraser les gestionnaires d'initialisation jdomain, puisque jdomain est techniquement aussi un module de répartition de charge. Bien que cela ne soit pas le cas avec tous les modules de répartition de charge, il est préférable de rester prudent et de placer jdomain après.
Remarque importante : En raison de la nature non bloquante de ce module et du fait que sa résolution DNS est déclenchée par des requêtes entrantes, la requête qui déclenche une recherche sera en fait toujours transmise au upstream qui a été résolu et mis en cache avant que la recherche DNS ne se produise. Selon le scénario, cela pourrait entraîner un échec ponctuel lors du changement des états des upstreams. Il est important de garder cela à l'esprit pour assurer des transitions en douceur de vos upstreams.
Ce dépôt est un fork d'un dépôt initialement rédigé par wdaike. Comme ce projet n'est plus maintenu, ce dépôt vise à être son successeur et a maintenant plusieurs fonctionnalités en avance.
Utilisation
resolver 8.8.8.8; # Votre serveur DNS local
## Upstream de base utilisant le nom de domaine par défaut sur le port 80.
upstream backend_01 {
jdomain example.com;
}
## Upstream de base spécifiant un port différent.
upstream backend_02 {
jdomain example.com port=8080;
}
## Upstream avec un serveur de secours à utiliser en cas d'hôte introuvable ou d'erreurs de format
## lors de la résolution DNS.
upstream backend_03 {
server 127.0.0.2 backup;
jdomain example.com;
}
## Upstream qui utilisera le secours pour toutes les erreurs de résolution DNS.
upstream backend_04 {
server 127.0.0.2 backup;
jdomain example.com strict;
}
server {
listen 127.0.0.2:80;
return 502 'Une erreur.';
}
Synopsis
Syntaxe : jdomain <nom-de-domaine> [port=80] [max_ips=4] [interval=1] [strict]
Contexte : upstream
Attributs :
port : Port d'écoute du backend. (Par défaut : 80)
max_ips : Taille du tampon IP. Nombre maximum d'IP résolues à mettre en cache. (Par défaut : 4)
interval : Combien de secondes pour résoudre le nom de domaine. (Par défaut : 1)
ipver : Seules les adresses de la famille IPv4 ou IPv6 seront utilisées si définies (Par défaut : 0)
strict : Exiger que la résolution DNS réussisse et renvoie des adresses,
sinon marque le serveur sous-jacent et les pairs comme étant hors service et
force l'utilisation d'autres serveurs dans le bloc upstream s'il y en a.
Une résolution échouée peut être un délai d'attente, une défaillance du serveur DNS,
des refus de connexion, une réponse sans adresses, etc.
Voir https://www.nginx.com/resources/wiki/modules/domain_resolve/ pour plus de détails.
Développement
Prérequis
Pour faciliter le développement local et vous permettre de construire et tester le module, vous aurez besoin de quelques outils.
- Docker : pour fournir un environnement pour reproduire facilement des conditions idéales pour la construction et le test.
- act : pour simuler l'exécution des workflows d'actions github localement afin de vous éviter de pousser des commits juste pour voir le CI échouer.
- rust : dépendance de
cargo-make. - cargo-make : pour exécuter des tâches de développement courantes telles que la construction, les tests et le formatage du code.
Exécuteur de tâches
cargo-make est un exécuteur de tâches avancé qui vous permettra d'effectuer facilement
des opérations de développement courantes comme le formatage du code, la construction du module,
l'exécution de la suite de tests et l'analyse de code. Vous pouvez voir les définitions de tâches dans le fichier Makefile.toml. L'installation de cargo-make donnera lieu à un exécutable autonome appelé makers ainsi qu'une extension cargo qui peut être exécutée via cargo make. Comme ce projet n'est pas une crate rust, il est recommandé d'utiliser simplement makers.
Notez également que, pour des raisons de simplicité, l'exécuteur de tâches utilise docker pour exécuter toutes les tâches. Cela signifie que le binaire de construction n'est pas ciblé sur votre plateforme hôte.
Tâche par défaut
Pour ajouter de la valeur, la tâche par défaut (c'est-à-dire simplement exécuter makers seul) commencera
une session bash interactive à l'intérieur du conteneur docker utilisé pour ce projet.
Cela devrait aider au débogage et au flux de travail général.
Formatage
Un code mal formaté fera échouer le travail de linting des actions github. Pour éviter cela, vous pouvez exécuter la tâche de formatage avant de pousser de nouveaux changements, comme ceci :
makers format
Ce formatage est effectué par un outil appelé clang-format. Vous pouvez trouver les options de configuration pour cela définies dans le fichier ./.clang-format.
Analyse statique du code
Vous pouvez exécuter une analyse statique sur le code via la tâche d'analyse :
makers analyse
Cette analyse est effectuée par un outil appelé clang-tidy. Vous pouvez trouver les options de configuration pour cela définies dans le fichier ./.clang-tidy.
Tests
Vous pouvez exécuter la suite de tests en utilisant la tâche de test, comme ceci :
makers test
Débogage
Nous pouvons utiliser valgrind et gdb sur nginx depuis l'intérieur du conteneur.
Ouvrez d'abord un shell interactif dans le conteneur avec :
$ makers
Nous utiliserons cette session pour exécuter valgrind :
$ valgrind --vgdb=full --vgdb-error=0 /github/workspace/bin/static/nginx -p/github/workspace/t/servroot -cconf/nginx.conf
==15== Memcheck, un détecteur d'erreurs de mémoire
==15== Copyright (C) 2002-2017, et GNU GPL, par Julian Seward et al.
==15== Utilisation de Valgrind-3.13.0 et LibVEX ; relancez avec -h pour des informations sur le copyright
==15== Commande : /github/workspace/bin/static/nginx -p/github/workspace/t/servroot -cconf/nginx.conf
==15==
==15== (action au démarrage) vgdb me ...
==15==
==15== POUR DÉBOGUER CE PROCESSUS EN UTILISANT GDB : démarrez GDB comme ceci
==15== /path/to/gdb /github/workspace/bin/static/nginx
==15== puis donnez à GDB la commande suivante
==15== target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=15
==15== --pid est optionnel si un seul processus valgrind est en cours d'exécution
==15==
Ensuite, trouvez l'identifiant du conteneur afin que nous puissions ouvrir une autre session à l'intérieur :
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55fab1e069ba act-github-actions-nginx-module-toolbox "bash" il y a 4 secondes En cours d'exécution 0.0.0.0:1984->1984/tcp serene_newton
Utilisez soit le nom soit l'ID pour exécuter une session bash à l'intérieur du conteneur :
$ docker exec -it serene_newton bash
Nous utiliserons cette session pour démarrer gdb et cibler le serveur gdb valgrind que nous avons démarré dans l'autre session :
$ gdb /github/workspace/bin/static/nginx
GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-30.amzn2.0.3
Copyright (C) 2017 Free Software Foundation, Inc.
Licence GPLv3+ : GNU GPL version 3 ou ultérieure <http://gnu.org/licenses/gpl.html>
Ce logiciel est libre : vous êtes libre de le modifier et de le redistribuer.
Il N'Y A AUCUNE GARANTIE, dans la mesure permise par la loi. Tapez "show copying"
et "show warranty" pour plus de détails.
Ce GDB a été configuré comme "x86_64-redhat-linux-gnu".
Tapez "show configuration" pour les détails de configuration.
Pour les instructions de signalement de bogues, veuillez consulter :
<http://www.gnu.org/software/gdb/bugs/>.
Trouvez le manuel GDB et d'autres ressources de documentation en ligne à :
<http://www.gnu.org/software/gdb/documentation/>.
Pour obtenir de l'aide, tapez "help".
Tapez "apropos mot" pour rechercher des commandes liées à "mot"...
Lecture des symboles depuis /github/workspace/bin/static/nginx...fait.
(gdb)
Depuis l'invite gdb, ciblez le processus valgrind et commencez le débogage :
(gdb) target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=15
Débogage à distance utilisant | /usr/lib64/valgrind/../../bin/vgdb --pid=15
transmission de données entre gdb et le processus 15
avertissement : la cible distante ne prend pas en charge le transfert de fichiers, tentative d'accès aux fichiers depuis le système de fichiers local.
Lecture des symboles depuis /lib64/ld-linux-x86-64.so.2...(aucun symbole de débogage trouvé)...fait.
0x0000000004000ef0 dans _start () depuis /lib64/ld-linux-x86-64.so.2
Informations de débogage manquantes, utilisez : debuginfo-install glibc-2.26-35.amzn2.x86_64
(gdb)
Exécution des actions GitHub
Avec act, vous pouvez simuler le workflow qui s'exécutera sur les serveurs GitHub une fois que vous aurez poussé des modifications.
Il y a plus d'un travail dans le workflow principal, donc vous devez spécifier le travail de test lorsque vous exécutez act. Par exemple, vous pouvez utiliser cette commande pour exécuter la validation du format de code :
act -vj lint
Notez que le travail lint ne formate pas votre code, il vérifie simplement que le formatage est conforme aux attentes.
Notez également que -v est utilisé pour activer le mode verbeux afin de donner plus de visibilité sur tout ce que act fait.
Les travaux que vous pouvez (et devez) exécuter localement sont lint, build, analyse et test. Le travail test dépend de la sortie du travail build. Pour conserver la sortie du travail de construction, vous pouvez ajouter le drapeau -b à act, ou vous pouvez simplement utiliser l'exécuteur de tâches pour construire.
Problèmes connus
Pour le moment ? Aucun ! 🎉
Si vous découvrez un bogue ou avez une question à poser, veuillez ouvrir un problème.
Auteur original
wdaike wdaike@163.com (https://github.com/wdaike), Baidu Inc.
GitHub
Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-upstream-jdomain.