Proxy_pass yaparken nginx'i DNS (dinamik bir ana bilgisayar adının) her defasında çözmesi için nasıl zorlarsınız?


52

Aşağıdaki yapılandırma ile CentOS'ta çalışan nginx / 0.7.68 kullanıyorum:

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

proxy_pass, IP sık sık değişen bir DNS kaydının etmektir. Nginx, eski IP adresini önbelleğe alır ve yanlış IP adresine istekte bulunur.

Modası geçmişken nginx'in IP adresini önbelleğe almasını nasıl durdurabilirim?


nginx kaynağına bakıldığında, nginx'in TTL'lerini gidermek için önbelleğe alınması zor kodlanmış görünüyor - dinamik dns'inizdeki TTL nedir?
lunixbochs

Ddns'imde TTL 60s, dyndns.com
xiamx


Yanıtlar:


8

Bu ilginç bir soru ve iyi çalışmayacak AFAIK. Sen kullanmayı deneyebilirsiniz memba modül ve bir hack olarak çalıştığını görmek için durumunda geçiş için direktifler kullanın.

2018 düzenleme: bir çok şey değişti. Bu konuda gerçek bilgi almak için cevap @ohaal tarafından kontrol edin .


1
şaşırtıcı bir şekilde yukarı akışa geçtiğimde, her şey beklendiği gibi çalıştı. Bunu doğru cevap olarak işaretleyeceğim
xiamx

1
Belgelere göre, yalnızca ticari sürümde mevcut olan özel bir yukarı akış serverbayrağı resolvevar (bkz. Nginx.org/en/docs/http/ngx_http_upstream_module.html#server )
omribahumi

1
Bu siteyi @gansbrest bir tür spam siteye benziyor mu? cevabınızı kaldırmanızı rica ediyorum.
majikman

90

Kabul edilen cevap benim için nginx / 1.4.2'de işe yaramadı.

Bir değişkeni kullanarak proxy_passDNS isimlerinin çözünürlüklü yeniden kuvvetlerin Nginx statik yapılandırmaya farklı değişkenleri davranır çünkü. Gönderen nginx proxy_passbelgelerinde :

Parametre değeri değişkenler içerebilir. Bu durumda, bir adres etki alanı adı olarak belirtilirse, ad açıklanan sunucu grupları arasında aranır ve bulunmazsa bir çözümleyici kullanılarak belirlenir.

Örneğin:

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

Not: Bir çözümleyici (kullanılacak isim sunucusu) bunun çalışması için mevcut ve yapılandırılmış olmalıdır (ve bir /etc/hostsdosya içindeki girişler bir aramada kullanılmayacaktır).

Varsayılan olarak, sürüm 1.1.9 veya sonraki sürümleri, NGINX önbellek sürümleri, bir yanıtın TTL değerini kullanarak yanıtlar ve isteğe bağlı bir validparametre önbellek zamanının geçersiz kılınmasına izin verir:

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

1.1.9 sürümünden önce, önbellekleme süresinin ayarlanması mümkün değildi ve nginx her zaman 5 dakika boyunca yanıtları önbelleğe aldı. .


bu her bir istek üzerine bir dns sorgusunu zorlamaz mı? Bu korkunç performansa benziyor ...
lucascaro

Hayır, kaynağı oku. In such setup ip address of "foo.example.com" will be looked up dynamically and result will be cached for 5 minutes.Açıklığa kavuşturmak için cevaba ekledim.
ohaal

13
Günümün çoğunu buna harcadıktan sonra - Ubuntu 12.04'te nginx 1.1.19 ile, setiçeri locationdüzgün çalışmıyor. Beware
omribahumi

Bu çözüm benimle birlikte çalıştı, ancak 5 dakikalık TTL için bir referans bulamadım. nginx.org/en/docs/http/ngx_http_core_module.html#resolver By default, nginx caches answers using the TTL value of a response. An optional valid parameter allows overriding it: resolver 127.0.0.1 [::1]:5353 valid=30s;
Montaro

4
Not: liman işçisi için, DNS çözümleyicisi 127.0.0.11'de bulunuyor, bu yüzden geliştirme için şunu kullanıyorum:resolver 127.0.0.11 [::1]:5353 valid=15s;
Dalibor Filus 11

9

Gansbrest yorumunda ve ohaal cevabında değerli bilgiler var.

Ancak 2016'da yayınlanan bu resmi nginx makalesinden bahsetmenin önemli olduğunu düşünüyorum, bu konuda nginx davranışını ve olası çözümleri açıkça açıklıyor: https://www.nginx.com/blog/dns-service-discovery-nginx-plus /

Gerçekten, "Etki Alanı Adını Bir Değişkene Ayarla" ve çözümleyici direktifini kullanmalıyız .

ancak değişken kullanmak yeniden yazma davranışını değiştirir. Yeniden yazma direktifini kullanmak zorunda kalabilirsiniz, bu konumunuza ve proxy_pass kurulumunuza bağlıdır.

Not: Bir yorum göndermiş ama henüz yeterli puan vermemiş.


1

ohaal'ın cevabı çoğumuzu oradan alıyor, ancak DNS çözümleyicisinin 127.0.0.1'de (örneğin özel bir konteynerlenmiş ortamdayken) yaşamadığı bir durum var.

Bu durumda, nginx conf komutunu değiştirmek isteyebilirsiniz resolver ${DNS_SERVER};. Sonra nginx'e başlamadan önce koşun

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

0

Ben dns değişiklikleri için bir conf.d klasör yukarı akışlarını izlemek ve algılama üzerine nginx yeniden yüklemek için bir komut dosyası hack. Bu bir ilk geçiş ve kesinlikle iyileştirilebilir (sonraki geçiş, özellikle akışları ayrıştırmak için nginx -T kullanacağım. Proxy_pass direktifleri için aynı fikir kullanılabilir):

#!/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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.