Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx proxy_pass directive string interpolation

I'm running Nginx on Kubernetes.

When I use the following proxy_pass directive it works as expected:

proxy_pass "http://service-1.default";

However the following does not work:

set $service "service-1";
proxy_pass "http://$service.default";

I get an error saying no resolver defined to resolve service-1.default

As far as I can tell proxy_pass is receiving the exact same string so why is it behaving differently?

I need to use a variable because I'm dynamically getting the service name from the URL using a regex.

like image 266
Mikhail Janowski Avatar asked Apr 10 '17 15:04

Mikhail Janowski


People also ask

What is proxy_pass in nginx?

The proxy_pass setting makes the Nginx reverse proxy setup work. The proxy_pass is configured in the location section of any virtual host configuration file. To set up an Nginx proxy_pass globally, edit the default file in Nginx's sites-available folder.

What is Proxy_redirect in nginx?

The proxy_redirect used above will rewrite all HTTP redirects from upstream to the current scheme, ie HTTPS. The browser will then receive the correct scheme directly, avoiding unnecessary round-trips.

What is Proxy_connect_timeout in nginx?

proxy_connect_timeout 60s; Context: http , server , location. Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.

What is Proxy_set_header Nginx?

Passing Headers to Handle Proxied Requests. Apart from proxy_pass, NGINX offers many other directives to handle requests to your server blocks. One of these directives is proxy_set_header, which lets you pass/rewrite headers to handle proxied requests.


1 Answers

I've found the reason and a solution.

Nginx detects if a variable is being used in proxy_pass (I don't know how it does that). If there is no variable it resolved the hostname at startup and caches the IP address. If there is a variable it uses a resolver (DNS server) to lookup the IP at runtime.

So the solution is to specify the Kube DNS server like this:

resolver kube-dns.kube-system.svc.cluster.local valid=5s;
set $service "service-1";
proxy_pass "http://$service.default.svc.cluster.local";

Note that the full local DNS name of the service must be used which you can get by running nslookup service-1.

like image 191
Mikhail Janowski Avatar answered Sep 21 '22 05:09

Mikhail Janowski