Làm cách nào để buộc nginx phân giải DNS (của tên máy chủ động) mọi lúc khi thực hiện proxy_pass?


52

Tôi đang sử dụng nginx / 0.7.68, chạy trên CentOS, với cấu hình sau:

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

Đây proxy_passlà bản ghi DNS có IP thay đổi thường xuyên. Nginx lưu trữ địa chỉ IP đã lỗi thời, dẫn đến yêu cầu địa chỉ IP sai.

Làm cách nào tôi có thể ngăn nginx lưu vào bộ nhớ cache địa chỉ IP, khi nó đã lỗi thời?


Nhìn qua nguồn nginx, có vẻ như nginx đã được mã hóa cứng để bộ nhớ cache phân giải cho TTL của họ - TTL trên dns động của bạn là gì?
lunixbochs

TTL trên ddns của tôi là 60 giây, giá trị mặc định của dyndns.com
xiamx


Câu trả lời:


8

Đó là một câu hỏi hấp dẫn và AFAIK sẽ không hoạt động tốt. Bạn có thể thử sử dụng mô-đun ngược dòng và sử dụng các lệnh cho chuyển đổi dự phòng để xem liệu nó có hoạt động như một bản hack hay không.

Chỉnh sửa năm 2018: rất nhiều thứ đã thay đổi. Kiểm tra câu trả lời của @ohaal để có được thông tin thực sự về điều này.


1
Thật ngạc nhiên khi tôi đổi sang thượng nguồn, mọi thứ hoạt động như mong đợi. Sau đó tôi sẽ đánh dấu đây là câu trả lời đúng
xiamx

1
Theo tài liệu, có một servercờ ngược dòng đặc biệt resolvechỉ có trong phiên bản thương mại (xem nginx.org/en/docs/http/ngx_http_upstream_module.html#server )
omribahumi

1
@gansbrest trang web đó dường như là một loại trang web spam? Tôi sẽ yêu cầu bạn loại bỏ phản hồi của bạn.
Majikman

90

Câu trả lời được chấp nhận không hoạt động với tôi trên nginx / 1.4.2.

Sử dụng một biến trong proxy_passlực lượng phân giải lại tên DNS vì NGINX xử lý các biến khác nhau đối với cấu hình tĩnh. Từ tài liệu NGINXproxy_pass :

Giá trị tham số có thể chứa các biến. Trong trường hợp này, nếu một địa chỉ được chỉ định là một tên miền, tên đó được tìm kiếm trong số các nhóm máy chủ được mô tả và, nếu không tìm thấy, được xác định bằng cách sử dụng trình phân giải.

Ví dụ:

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

Lưu ý: Trình phân giải (tức là máy chủ tên sẽ sử dụng) PHẢI có sẵn và được định cấu hình để hoạt động này (và các mục bên trong /etc/hoststệp sẽ không được sử dụng trong tra cứu).

Theo mặc định, phiên bản 1.1.9 trở lên của các câu trả lời bộ đệm NGINX sử dụng giá trị TTL của phản hồivalidtham số tùy chọn cho phép ghi đè thời gian bộ đệm:

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

Trước phiên bản 1.1.9, không thể điều chỉnh thời gian lưu vào bộ đệm và nginx luôn lưu các câu trả lời trong bộ nhớ cache trong thời gian 5 phút. .


điều này sẽ buộc một truy vấn dns trên mỗi yêu cầu? Nghe có vẻ là hiệu suất khủng khiếp ...
lucascaro 10/03/2015

Không, đọc nguồn. In such setup ip address of "foo.example.com" will be looked up dynamically and result will be cached for 5 minutes.Tôi đã thêm nó vào câu trả lời cho rõ ràng.
ohaal

13
Sau khi dành phần lớn thời gian của tôi cho việc này - trên Ubuntu 12.04 với nginx 1.1.19, setbên trong locationkhông hoạt động đúng. Cẩn thận
omribahumi

Giải pháp này đã làm việc với tôi, tuy nhiên tôi không thể tìm thấy tài liệu tham khảo trong 5 phút 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
Lưu ý: đối với docker, trình phân giải DNS của nó nằm ở 127.0.0.11, vì vậy để phát triển, tôi sử dụng điều này:resolver 127.0.0.11 [::1]:5353 valid=15s;
Dalibor Filus

9

Có thông tin có giá trị trong bình luận gansbrest và câu trả lời ohaal.

Nhưng tôi nghĩ điều quan trọng là phải đề cập đến bài viết nginx chính thức này, được đăng vào năm 2016, nó giải thích rõ ràng hành vi nginx về vấn đề này và các giải pháp khả thi: https://www.nginx.com/blog/dns-service-discovery-nginx-plus /

Chúng tôi thực sự phải "Đặt tên miền thành một biến" và sử dụng chỉ thị trình giải quyết .

tuy nhiên, sử dụng một biến sẽ thay đổi hành vi viết lại. Bạn có thể phải sử dụng lệnh viết lại, nó phụ thuộc vào vị trí và thiết lập proxy_pass của bạn.

PS: sẽ đăng một bình luận nhưng chưa đủ điểm ...


1

Câu trả lời của ohaal đưa hầu hết chúng ta đến đó, nhưng có một trường hợp trình phân giải DNS không tồn tại ở 127.0.0.1 (ví dụ: khi bạn ở trong một môi trường được chứa đặc biệt)

Trong trường hợp đó, bạn có thể muốn thay đổi nginx conf thành resolver ${DNS_SERVER};. Sau đó, trước khi bạn bắt đầu nginx, hãy chạy

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

Tôi đã hack cùng một tập lệnh để xem thư mục conf.d ngược dòng để thay đổi dns và tải lại nginx khi phát hiện. Đó là đường chuyền đầu tiên và chắc chắn có thể được cải thiện (đường chuyền tiếp theo, tôi sẽ sử dụng nginx -T để phân tích cú pháp ngược dòng cụ thể. Ý tưởng tương tự có thể được sử dụng cho các chỉ thị 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.