Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic proxy_pass in nginx to another pod in Kubernetes

I'm trying to create an nginx proxy that forwards requests to /<service> to http://<service>. I first tried the following:

location ~ ^/(.+)$ {
    set $backend "http://$1:80";
    proxy_pass $backend;
}

But it fails saying something like (when calling /myservice):

[error] 7741#0: *1 no resolver defined to resolve http://myservice

Since myservice is not externally accessible I've tried to install go-dnsmasq as a sidecar in the same pod and I try to use it for DNS resolution (like I've seen in this example) and change my nginx config to look like this:

location ~ ^/(.+)$ {
        resolver 127.0.0.1:53;
        set $backend "http://$1:80";
        proxy_pass $backend;
}

But now nginx fails with:

[error] 9#9: *734 myservice could not be resolved (2: Server failure), client: 127.0.0.1, server: nginx-proxy, request: "GET /myservice HTTP/1.1", host: "localhost:8080"
127.0.0.1 - xxx [30/May/2016:10:34:23 +0000] "GET /myservice HTTP/1.1" 502 173 "-" "curl/7.38.0" "-"

My Kubernetes pod looks like this:

spec:
  containers:
    - name: nginx
      image: "nginx:1.10.0"
      ports:
        - containerPort: 8080
          name: "external"
          protocol: "TCP"
    - name: dnsmasq
      image: "janeczku/go-dnsmasq:release-1.0.5"
      args:
        - --listen
        - "0.0.0.0:53"

Running netstat -ntlp in the dnsmasq container gives me:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      -
tcp        0      0 :::53                   :::*                    LISTEN      1/go-dnsmasq

And running nmap --min-parallelism 100 -sT -sU localhost in the nginx container:

Starting Nmap 6.47 ( http://nmap.org ) at 2016-05-30 10:33 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00055s latency).
Other addresses for localhost (not scanned): 127.0.0.1
Not shown: 1997 closed ports
PORT     STATE SERVICE
53/tcp   open  domain
8080/tcp open  http-proxy
53/udp   open  domain

So it seems that dnsmasq and nginx are indeed up and running? What could I be doing wrong?

like image 283
Johan Avatar asked May 30 '16 10:05

Johan


People also ask

How do I connect one pod to another pod in Kubernetes?

A Pod can communicate with another Pod by directly addressing its IP address, but the recommended way is to use Services. A Service is a set of Pods, which can be reached by a single, fixed DNS name or IP address. In reality, most applications on Kubernetes use Services as a way to communicate with each other.

What does Proxy_pass to 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.

How do you connect Nginx pods?

Open the web browser from the local machine and access type the Kubernetes node IP along with the Node port. Nginxwebpage. We are able to access the Nginx homepage successfully. It's a containerized web server listening in the port 80 and we mapped it to 30080 in every node in the cluster.

Is Kubernetes reverse proxy?

An ingress controller acts as a reverse proxy and load balancer.


1 Answers

After much research and trial and error I managed to solve this. First I changed the pod specification to:

spec:
  containers:
    - name: nginx
      image: "nginx:1.10.0"
      ports:
        - containerPort: 8080
          name: "external"
          protocol: "TCP"
    - name: dnsmasq
      image: "janeczku/go-dnsmasq:release-1.0.5"
      args:
        - --listen
        - "127.0.0.1:53"
        - --default-resolver
        - --append-search-domains
        - --hostsfile=/etc/hosts
        - --verbose

then I also had to disable the ipv6 for the resolver in nginx:

location ~ ^/(.+)$ {
        resolver 127.0.0.1:53 ipv6=off;
        set $backend "http://$1:80";
        proxy_pass $backend;
}

Then it works as expected!

like image 119
Johan Avatar answered Sep 30 '22 14:09

Johan