J'utilise nginx/0.7.68, fonctionnant sur CentOS, avec la configuration suivante:
server {
listen 80;
server_name ***;
index index.html index.htm index.php default.html default.htm default.php;
location / {
root /***;
proxy_pass http://***:8888;
index index.html index.htm;
}
# where *** is my variables
Le proxy_pass
correspond à un enregistrement DNS dont l'IP change fréquemment. Nginx met en cache l'adresse IP obsolète, entraînant une demande à la mauvaise adresse IP.
Comment puis-je empêcher nginx de mettre en cache l'adresse IP lorsqu'elle est obsolète?
C'est une question intrigante et l'AFAIK ne va pas bien fonctionner. Vous pouvez essayer d'utiliser le module en amont et utiliser les directives de basculement pour voir s'il fonctionne comme un hack.
Édition 2018: beaucoup de choses ont changé. Vérifiez le réponse de @ohaal pour obtenir de vraies informations à ce sujet.
La réponse acceptée n'a pas fonctionné pour moi sur nginx/1.4.2.
tilisation d'une variable dans proxy_pass
force la re-résolution des noms DNS car NGINX traite les variables différemment de la configuration statique. Depuis le NGINX proxy_pass
documentation :
La valeur du paramètre peut contenir des variables. Dans ce cas, si une adresse est spécifiée en tant que nom de domaine, le nom est recherché parmi les groupes de serveurs décrits et, s'il n'est pas trouvé, est déterminé à l'aide d'un résolveur.
Par exemple:
server {
...
resolver 127.0.0.1;
set $backend "http://dynamic.example.com:80";
proxy_pass $backend;
...
}
Remarque: Un résolveur (c'est-à-dire le serveur de noms à utiliser) DOIT être disponible et configuré pour que cela fonctionne (et les entrées dans un /etc/hosts
le fichier ne sera pas utilisé dans une recherche).
Par défaut, la version 1.1.9 ou les versions ultérieures du cache NGINX répondent en utilisant la valeur TTL d'une réponse et une option valid
paramètre permet de remplacer le temps de cache:
resolver 127.0.0.1 [::1]:5353 valid=30s;
Il y a des informations précieuses dans le commentaire de Gansbrest et la réponse d'Ohaal.
Mais je pense qu'il est important de mentionner cet article officiel de nginx, publié en 2016, il explique clairement le comportement de nginx à ce sujet et les solutions possibles: https://www.nginx.com/blog/dns-service-discovery -nginx-plus /
Nous devons en effet "définir le nom de domaine dans une variable" et utiliser la directive resolver .
cependant, l'utilisation d'une variable modifie le comportement de réécriture. Vous devrez peut-être utiliser la directive de réécriture, cela dépend de votre emplacement et de la configuration de proxy_pass.
PS: aurait posté un commentaire mais pas encore assez de points ...
la réponse de ohaal nous emmène presque partout, mais il y a un cas où le résolveur DNS ne vit pas à 127.0.0.1 (par exemple lorsque vous êtes dans un environnement conteneurisé spécial)
Dans ce cas, vous souhaiterez peut-être modifier la conf nginx en resolver ${DNS_SERVER};
. Ensuite, avant de démarrer nginx, exécutez
export DNS_SERVER=$(cat /etc/resolv.conf |grep -i '^nameserver'|head -n1|cut -d ' ' -f2)
envsubst '${DNS_SERVER} < your_nginx.conf.template > your_nginx.conf
J'ai piraté un script pour regarder un dossier conf.d en amont pour les modifications DNS et recharger nginx lors de la détection. C'est une première passe, et peut sûrement être améliorée (prochaine passe, je vais utiliser nginx -T pour analyser spécifiquement en amont. La même idée pourrait être utilisée pour les directives proxy_pass):
#!/bin/bash
get_upstreams() {
local files=$@
grep -hEo '(server\s+)[^:;]+' $files | cut -d' ' -f 2
}
resolve_hosts() {
local hosts=$@
for h in $hosts; do Dig +short $h; done | sort -u
}
watch_dir=$1
[ -d $watch_dir ] || exit 2
upstreams=$(get_upstreams $watch_dir/*)
ips=$(resolve_hosts $upstreams)
if [ ! "$ips" ]; then
echo "Found no resolvable hosts in $watch_dir files."
fi
Host_hash=$(echo $ips | /usr/bin/sha512sum)
echo $Host_hash
echo $ips
while [ -d $watch_dir ]; do
sleep 30
upstreams=$(get_upstreams $watch_dir/*)
ips=$(resolve_hosts $upstreams)
new_hash=$(echo $ips | /usr/bin/sha512sum)
if [ "$Host_hash" != "$new_hash" ]; then
echo Detected an upstream address change. $ips
echo Reloading nginx
echo $new_hash
echo $ips
/sbin/service nginx reload
Host_hash=$new_hash
fi
done