I needed to map a custom sub-path in Kubernetes to a backend service I was running in Azure Kubernetes Service.
I wanted something like this:
Naturally, I needed to configure my Ingress Component to allow this. I attempted to write a valid Ingress Component to expose both my client & my server though the same root URL, with different sub-paths. The client part of the ingress worked without issue, but the server didn’t.
Here is the server Ingress Component configuration.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: containers-everywhere-server-ingress annotations: kubernetes.io/ingress.class: nginx spec: rules: - http: paths: - path: /server pathType: Prefix backend: service: name: containers-everywhere-server-service port: number: 80
What I didn’t understand was what NGINX was appending to the requests to the backend service. By default, NGINX is going to pass the entire URL that is specified by sending it to the backend service.
URL sent to backend service
Naturally, my backend service thinks it is the center of the universe, so it doesn’t know anything about the
server keyword I added to differentiate the services in the Ingress Component.
Therefore, I needed to re-write the URL that is passed to the backend service.
The documentation states that I need to provide a regex & specify some annotations that will get passed to the underlying NGINX Ingress Component.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 ... spec: rules: - http: paths: - path: /something(/|$)(.*) ...
If we look at the regex specified in a tool like https://regex101.com, we can see that 2 capture groups will appear.
The most important part of this regex is the capture group that has the actual path on the server application I want to access (in this case, the Swagger documentation).
This is specified in the
annotations section of the Kubernetes Ingress Component (using the
The documentation does state what is happening, but I didn’t understand what was going to be captured in the various capture groups.
My original code didn’t have the
rewrite-target annotation at all and then the 2nd time I did it, I copied/pasted code from Stack Overflow without understanding what it was really doing (not that anyone else has ever done this :)).
This was mapping requests to the root of my server application, which isn’t going to respond.
The correct Ingress in the end is:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: containers-everywhere-server-ingress annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - path: /server(/|$)(.*) pathType: Prefix backend: service: name: containers-everywhere-server-service port: number: 80
This Ingress Component will match any requests to the
server sub-path, forward requests to the
containers-everywhere-server-service and the part of the URL after
server will get added to a request starting at the root of the web server.
In the end, the message is RTFM.