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.