it-swarm.com.de

Wie kann man nginx zwingen, DNS (eines dynamischen Hostnamens) jedes Mal aufzulösen, wenn proxy_pass ausgeführt wird?

Ich verwende nginx/0.7.68 unter CentOS mit der folgenden Konfiguration:

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

Das proxy_pass bezieht sich auf einen DNS-Eintrag, dessen IP sich häufig ändert. Nginx speichert die veraltete IP-Adresse zwischen, was zu einer Anforderung an die falsche IP-Adresse führt.

Wie kann ich verhindern, dass nginx die IP-Adresse zwischenspeichert, wenn sie veraltet ist?

58
xiamx

Es ist eine faszinierende Frage und AFAIK, die nicht gut funktionieren wird. Sie können versuchen, das Modul pstream zu verwenden und die Anweisungen für das Failover zu verwenden, um festzustellen, ob es als Hack funktioniert.

2018 bearbeiten: viele Dinge haben sich geändert. Überprüfen Sie die Antwort von @ohaal , um echte Informationen darüber zu erhalten.

9
coredump

Die akzeptierte Antwort hat bei Nginx/1.4.2 bei mir nicht funktioniert.

Verwenden einer Variablen in proxy_pass erzwingt eine erneute Auflösung der DNS-Namen , da NGINX Variablen anders behandelt als die statische Konfiguration. Aus dem NGINX proxy_pass Dokumentation :

Der Parameterwert kann Variablen enthalten. Wenn in diesem Fall eine Adresse als Domänenname angegeben wird, wird der Name unter den beschriebenen Servergruppen gesucht und, falls er nicht gefunden wird, mithilfe eines Resolvers ermittelt.

Zum Beispiel:

server {
    ...
    resolver 127.0.0.1;
    set $backend "http://dynamic.example.com:80";
    proxy_pass $backend;
    ...
}

Hinweis: Ein Resolver (d. H. Der zu verwendende Nameserver) MUSS verfügbar und konfiguriert sein, damit dies funktioniert (und Einträge in einem /etc/hosts Datei wird nicht in einer Suche verwendet).

Standardmäßig antwortet Version 1.1.9 oder eine neuere Version des NGINX-Cache mit dem Wert TTL Wert einer Antwort und einem optionalen valid Parameter ermöglicht das Überschreiben der Cache-Zeit:

resolver 127.0.0.1 [::1]:5353 valid=30s;

Vor Version 1.1.9 war eine Optimierung der Caching-Zeit nicht möglich, und nginx hat Antworten immer für die Dauer von 5 Minuten zwischengespeichert. =.

97
ohaal

Es gibt wertvolle Informationen in Gansbrest Kommentar und Ohaal Antwort.

Ich denke jedoch, dass es wichtig ist, diesen offiziellen Nginx-Artikel zu erwähnen, der 2016 veröffentlicht wurde. Er erklärt klar das Nginx-Verhalten in dieser Angelegenheit und die möglichen Lösungen: https://www.nginx.com/blog/dns-service-discovery -nginx-plus /

Wir müssen in der Tat "den Domainnamen in einer Variablen festlegen" und die Direktive Resolver verwenden.

die Verwendung einer Variablen ändert jedoch das Umschreibverhalten. Möglicherweise müssen Sie die Anweisung zum Umschreiben verwenden. Dies hängt von Ihrem Standort und dem Setup von proxy_pass ab.

PS: hätte einen Kommentar gepostet, aber noch nicht genug Punkte ...

9
Jack B.

die Antwort von ohaal führt die meisten von uns dorthin, aber es gibt einen Fall, in dem der DNS-Resolver nicht unter 127.0.0.1 lebt (z. B. wenn Sie sich in einer speziellen Containerumgebung befinden).

In diesem Fall möchten Sie möglicherweise die Nginx-Konfiguration in resolver ${DNS_SERVER}; Ändern. Bevor Sie nginx starten, führen Sie es aus

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
3
wonton

Ich habe ein Skript gehackt, um einen conf.d-Ordner stromaufwärts auf DNS-Änderungen zu überwachen und nginx bei Erkennung neu zu laden. Es ist ein erster Durchgang und kann sicherlich verbessert werden (im nächsten Durchgang verwende ich nginx -T, um Upstreams spezifisch zu analysieren. Dieselbe Idee könnte für proxy_pass-Direktiven verwendet werden):

#!/bin/bash

get_upstreams() {
  local [email protected]
  grep -hEo '(server\s+)[^:;]+' $files | cut -d' ' -f 2
}

resolve_hosts() {
  local [email protected]
  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
0
mushuweasel