Como forçar o nginx a resolver o DNS (de um nome de host dinâmico) toda vez que fizer proxy_pass?

37

Estou usando o nginx / 0.7.68, rodando no CentOS, com a seguinte configuração:

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

O proxy_pass é para um registro DNS cujo IP muda com freqüência. O Nginx armazena em cache o endereço IP desatualizado, resultando em uma solicitação para o endereço IP incorreto.

Como posso impedir que o nginx armazene em cache o endereço IP, quando ele está desatualizado?

    
por xiamx 26.02.2011 / 01:55

4 respostas

7

É uma pergunta intrigante e AFAIK que não vai funcionar bem. Você pode tentar usar o módulo upstream e usar as diretivas para failover para ver se funciona como um hack .

2018 edit: muitas coisas mudaram. Verifique a resposta de @ohaal para obter informações reais sobre isso.

    
por 26.02.2011 / 02:19
65

A resposta aceita não funcionou para mim no nginx / 1.4.2.

A definição de proxy_pass para uma variável força a nova resolução dos nomes DNS, porque o Nginx trata as variáveis de maneira diferente da configuração estática. [1]

Exemplo:

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

Observação: um resolvedor (por exemplo, o servidor de nomes que você usa) DEVE ser configurado para que isso funcione.

Por padrão, o nginx armazena em cache as respostas usando o valor TTL de uma resposta. Um parâmetro válido opcional permite substituí-lo: [2]

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

Antes da versão 1.1.9, o ajuste do tempo de armazenamento em cache não era possível, e o nginx sempre armazenava as respostas em cache durante 5 minutos.

Fontes:
[1] link
[2] link

    
por 04.05.2014 / 11:59
6

Há informações valiosas no comentário do gansbrest e na resposta do ohaal.

Mas acho importante mencionar esse artigo oficial do nginx, publicado em 2016, que explica claramente o comportamento do nginx sobre esse assunto e as possíveis soluções: link

Nós realmente temos que "Definir o nome de domínio em uma variável" e usar o resolver directiva.

no entanto, usar uma variável altera o comportamento de reescrita. Você pode ter que usar a diretiva de reescrita, isso depende da sua localização e da configuração proxy_pass.

PS: teria que postar um comentário, mas não pontos suficientes ainda ...

    
por 23.06.2017 / 23:37
0

Eu juntei um script para ver uma pasta conf.d atualizar as alterações do DNS e recarregar o nginx após a detecção. É uma primeira passagem, e certamente pode ser melhorada (na próxima passagem, eu usarei o nginx -T para analisar especificamente o upstream. A mesma idéia pode ser usada para diretivas 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
    
por 24.04.2018 / 03:21

Tags