proxy_pass를 수행 할 때마다 nginx가 동적 호스트 이름의 DNS를 강제로 해결하는 방법은 무엇입니까?


52

CentOS에서 다음과 같은 구성으로 nginx / 0.7.68을 사용하고 있습니다.

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 자주 변경하는 DNS 레코드입니다. Nginx는 오래된 IP 주소를 캐시하여 잘못된 IP 주소를 요청합니다.

IP 주소가 오래되었을 때 nginx가 캐싱하지 못하게하려면 어떻게해야합니까?


nginx 소스를 살펴보면 nginx가 TTL에 대한 분석을 캐시하도록 하드 코딩 된 것처럼 보입니다. 동적 DNS의 TTL은 무엇입니까?
— lunixbochs

내 DDNS에 TTL은 60, dyndns.com의 기본값입니다
— xiamx


답변:


8

흥미로운 질문과 AFAIK는 잘 작동하지 않습니다. 당신이 사용하려고 할 수 있습니다 업스트림 모듈을하고 해킹으로 작동하는지 확인하기 위해 장애 복구에 대한 지침을 사용합니다.

2018 편집 : 많은 것들이 변경되었습니다. 이에 대한 실제 정보를 얻으려면 @ohaal 의 답변을 확인하십시오 .


1
놀랍게도 내가 업스트림으로 바꿨을 때 모든 것이 예상대로 작동했습니다. 그때 나는이 같은 정답 표시합니다
— xiamx

1
문서에 따르면 상용 버전에서만 사용할 수 있는 특수 업스트림 server플래그 resolve가 있습니다 ( nginx.org/en/docs/http/ngx_http_upstream_module.html#server 참조 )
— omribahumi

1
@gansbrest 해당 사이트는 일종의 스팸 사이트 인 것 같습니다. 답변을 삭제 해달라고 요청합니다.
— majikman 2016 년

90

수락 된 답변이 nginx / 1.4.2에서 작동하지 않았습니다.

proxy_passNGINX는 변수를 정적 구성과 다르게 취급하기 때문에 변수를 사용 하면 DNS 이름이 다시 해결 됩니다. 로부터 의 nginx의 proxy_pass문서 :

매개 변수 값은 변수를 포함 할 수 있습니다. 이 경우, 주소가 도메인 이름으로 지정된 경우, 이름은 설명 된 서버 그룹 중에서 검색되며, 발견되지 않은 경우 확인자를 사용하여 결정됩니다.

예를 들면 다음과 같습니다.

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

참고 : 리졸버 (즉, 사용할 네임 서버)를 사용할 수 있어야하며이 작업을 수행 할 수 있어야합니다 ( /etc/hosts파일 내의 항목 은 조회에 사용되지 않습니다).

기본적으로, 버전 1.1.9 이상의 NGINX 캐시 버전은 응답의 TTL 값을 사용하여 응답 하며 선택적 valid매개 변수를 사용하면 캐시 시간을 대체 할 수 있습니다.

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

버전 1.1.9 이전에는 캐싱 시간 조정이 불가능했으며 nginx는 항상 5 분 동안 응답을 캐시했습니다. .


이것은 모든 단일 요청에 대해 dns 쿼리를 강제하지 않습니까? 그것은 끔찍한 성능처럼 들립니다 ...
— lucascaro

아니요, 출처를 읽으십시오. In such setup ip address of "foo.example.com" will be looked up dynamically and result will be cached for 5 minutes.명확성을 위해 답변에 추가했습니다.
— ohaal

13
nginx 1.1.19가있는 Ubuntu 12.04에서 하루의 대부분을 보낸 후 set내부 location가 제대로 작동하지 않습니다. 조심
— omribahumi

이 솔루션은 나와 함께 일했지만 5 분 TTL에 대한 참조를 찾을 수 없습니다. 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
참고 : 도커의 경우 DNS 확인자가 127.0.0.11에 있으므로 개발을 위해 다음을 사용합니다.resolver 127.0.0.11 [::1]:5353 valid=15s;
— Dalibor Filus

9

gansbrest 코멘트와 ohaal answer에는 귀중한 정보가 있습니다.

그러나 2016 년에 게시 된이 공식 nginx 기사를 언급하는 것이 중요하다고 생각합니다.이 문제와 가능한 해결책에 대한 nginx 동작을 명확하게 설명합니다 : https://www.nginx.com/blog/dns-service-discovery-nginx-plus /

실제로 "변수에 도메인 이름을 설정"하고 리졸버 지시문을 사용해야합니다 .

그러나 변수를 사용하면 재 작성 동작이 변경됩니다. rewrite 지시문을 사용해야 할 수도 있으며 위치 및 proxy_pass 설정에 따라 다릅니다.

추신 : 의견을 게시했지만 아직 충분한 점수가 없습니다 ...


1

ohaal의 답변은 우리 대부분을 차지하지만 DNS 확인자가 127.0.0.1에 있지 않은 경우가 있습니다 (예 : 특수 컨테이너 환경에있는 경우)

이 경우 nginx conf를로 변경할 수 있습니다 resolver ${DNS_SERVER};. 그런 다음 nginx를 시작하기 전에 다음을 실행하십시오.

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

스크립트를 해킹하여 ns. 변경 사항에 대한 conf.d 폴더 업스트림을보고 감지시 nginx를 다시로드했습니다. 첫 번째 단계이며 확실히 향상 될 수 있습니다 (다음 단계에서는 nginx -T를 사용하여 업스트림을 구체적으로 파싱합니다. 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.