Paths are not working in Kubernetes NGINX Ingress Controller

8/13/2019

I have a Spring Boot application responsible for getting citizens and a NGINX Ingress controller configured with ssl-passthrough to expose my cluster to outside.

When I do: https://myhostname.com/citizens

It perfectly works. This is the configuration I am using:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
    - host: myhostname.com
      http:
        paths:
          - path: /
            backend:
              serviceName: myservice
              servicePort: 443

But I would like to have something like:

https://myhostname.com/myservice/citizens

It would be something similar to math Simple fanout approach that is described in the kubernetes docs: https://kubernetes.io/docs/concepts/services-networking/ingress/#simple-fanout

Therefore, in my Spring application I have configured a contextPath so when locally I do: https://localhost:8080/myservice/citizens

I get the desired result

For NGINX I have set up the following:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myhostname.com
      http:
        paths:
          - path: /myservice
            backend:
              serviceName: myservice
              servicePort: 443

What am I doing wrong?


Solution: I've been researching a little and I've realized that the approach that I was trying to achieve is not possible with ssl-passthrough as the proxy is blind and it doesn't know the path to where route the traffic.

Therefore, the solution would be to use subdomains and not paths, because thanks to the SNI protocol, the NGINX controller will know to which hostname the client is trying to connect.

The final solution would be something similar to this

-- Pablo GarcĂ­a Miranda
docker-ingress
kubernetes
kubernetes-ingress
nginx
ssl

1 Answer

8/14/2019

If your backend is expecting the whole path /myservice/citizens you can just use it to point it to the service without the rewrite-target directive, since it only dictates how URIs are going to be treated in the backend:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
    - host: myhostname.com
      http:
        paths:
          - path: /myservice/citizens
            backend:
              serviceName: myservice
              servicePort: 443

Be aware that this assumes that your service is able to redirect requests to 8080, which is your backend listening port, so it has to match it.

-- yyyyahir
Source: StackOverflow