Saita
Saita

Reputation: 1044

How to make NGINX re-resolve DNS?

I have a central nginx responding at router.mydomain.com. It has some proxypasses to different nginxes:

server {
    listen 8080;
    server_name nginx_server;
    port_in_redirect off;

    location / {
        root /html;
        index index.html index.htm;
    }

    location  /site1/ {
        proxy_pass         https://site1.mydomain.com;
        proxy_buffer_size          128k;
        proxy_buffers              4 256k;
        proxy_busy_buffers_size    256k;
    }

    location  /site2/ {
        proxy_pass         https://site2.mydomain.com;
        proxy_buffer_size          128k;
        proxy_buffers              4 256k;
        proxy_busy_buffers_size    256k;
    }

Both these sites are nginxes hosted in a kubernetes environment.

Now, the issue is, everytime I deploy site1 or site2, in kubernetes the route is properly updated so if https://site1.mydomain.com was pointing to a particular docker instance #1, and the new deploy is a docker instance #2, the url https://site1.mydomain.com how then point to docker instance #2.

This all works fine, but router.mydomain.com keeps pointing to the IP first resolved to the #1 instance.

router ---> https://site1 ---> docker #1 (ip: 123.456.789)


router ---> https://site1 ---> docker #1 (ip: 123.456.789)
                          \--> docker #2 (ip: 234.567.890)


router ---> https://site1 -X-> docker #1 (ip: 123.456.789)
                          \--> docker #2 (ip: 234.567.890)

router (still pointing to ip: 123.456.789) -X-> https://site1 ---> docker #2 (ip: 234.567.890)

How can I make nginx "notice" the dns changed? Should I just turn off dns caching entirely? Can I make nginx cache dns for a shorter time? How?

Upvotes: 4

Views: 7720

Answers (1)

Ivan Shatsky
Ivan Shatsky

Reputation: 15662

nginx has its own non-blocking resolving code, but in order to use it you need to specify a resolver using resolver directive. Here you can find some technical details why authors of nginx implements such a mechanism. You can use your local name server if you have one, or use something external like Google public DNS (8.8.8.8, 8.8.4.4) or DNS provided for you by your ISP:

resolver 8.8.8.8;

You can specify the timeout while last resolved names are valid:

resolver 8.8.8.8 valid=30s;

Unless you do this, nginx will resolve your domain names from configuration file only once at startup.

For your case, it's make sense to use one of the authoritative name servers for your domain. In order to get the list of that servers you can use the following command:

nslookup -type=ns mydomain.com

Your final configuration will be looking something like

server {
    listen 8080;
    server_name nginx_server;
    port_in_redirect off;
    resolver <your_authoritative_name_server> valid=<timeout>;

    location / {
        root /html;
        index index.html index.htm;
    }

    location  /site1/ {
        proxy_pass         https://site1.mydomain.com;
        proxy_buffer_size          128k;
        proxy_buffers              4 256k;
        proxy_busy_buffers_size    256k;
    }

    location  /site2/ {
        proxy_pass         https://site2.mydomain.com;
        proxy_buffer_size          128k;
        proxy_buffers              4 256k;
        proxy_busy_buffers_size    256k;
    }
}

Since you are working with docker, this question may be of interest to you too: nginx in docker proxy path to subdomain

Upvotes: 3

Related Questions