12

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.

Mikhail Janowski
  • 4,209
  • 7
  • 28
  • 40

1 Answers1

21

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.

Mikhail Janowski
  • 4,209
  • 7
  • 28
  • 40
  • For the docker-compose folks: the DNS server is always at `127.0.0.11` https://docs.docker.com/v17.09/engine/userguide/networking/configure-dns/ – Naramsim Nov 28 '18 at 09:38