Ingress rewrite to another Ingress

8/6/2020

I have two services running in kubernetes with url say https://service1.abc.cloud.com and https://service2.abc.cloud.com. I have routes defined in Ingress of both the services, for example my swagger path is https://service1.abc.cloud.com/docs and in ingress I have defined /docs to go to my service at SSO port 8082. Once SSO is successfull SSO redirects to my service1/docs route.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "service1.fullname" . }}
  labels:
{{ include "service1.labels" . | indent 4 }}
{{ include "chart.labels" . | indent 4 }}
  annotations:
{{ include "service1.annotations" . | indent 4 }}
spec:
  rules:
    - host: {{ template "service1.dns" . }}
      http:
        paths:
          - path: /docs
            backend:
              serviceName: {{ template "service1.fullname" . }}
              servicePort: 8082

Similar ingress file is for service2.

Till now the story was all good, but there is requirement popped up that we need to have a common url for all the services and the path param for the common url will have the service name. So we have 2 ingress file for service1 and service2 now.

The new url for service1 and service2 will be:-

https://mynamespace.abc.cloud.com/service1
https://mynamespace.abc.cloud.com/service2

I created a common ingress file for mynamespace host as below. So now, I have 3 ingress file one for mynamespace , one for service1 and one for service2. I know it should be one ingress file doing all the routes mapping but untill we deprecate the service1 and service2 urls we need to support the older service1 and service2 urls. Once we deprecate, we will be merging all code in one deployment and ingress.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "mynamespace.fullname" . }}
  labels:
{{ include "mynamespace.labels" . | indent 4 }}
{{ include "chart.labels" . | indent 4 }}
  annotations:
{{ include "mynamespace.ingress.annotations" . | indent 4 }}
spec:
  rules:
    - host: {{ template "iot.dns" . }}
      http:
        paths:
          - path: /mynamespace/docs
            backend:
              serviceName: {{ template "service1.fullname" . }}
              servicePort: 8082

Problem is I'm not able to route /mynamespace/docs of mynamespace host to /docs of service1 host. I also have SSO sidecar which is at port 8082 and my service1 and service2 is at port 8080.

End goal to be achieved:- When user hits url https://mynamespace.abc.cloud.com/service1/docs it should internally open the service1 swagger file which is hosted at https://service1.abc.barco.cloud.com/docs. The url in browser should not change so redirect should happen at kubernetes level and url should not change in browser. Since i need to support old urls too, they should also work i.e. https://service1.abc.cloud.com and https://service2.abc.cloud.com

Old design below:- enter image description here

New design below:- enter image description here

-- iAviator
kubernetes
kubernetes-helm
kubernetes-ingress
kubernetes-pod
nginx-ingress

1 Answer

8/7/2020

I am putting my best guess here:

You are trying to route mynamespace.abc.cloud.com/service1/docs to service1:8082/docs. You are having difficulty to convert the external path /service1/docs to the internal path /docs of service1

If that is the case, what your ingress needs is the rewrite-target and use-regex annotations:

nginx.ingress.kubernetes.io/rewrite-target: /docs/$2
nginx.ingress.kubernetes.io/use-regex: "true"

And the path definition needs to be suffixed with (/|$)(.*):

- path: /service1/docs(/|$)(.*)
-- Lukman
Source: StackOverflow