Kubernetes Ingress from Nginx ProxyPass For Complete Context Switch Within Services

The Complete Guide to Nginx conf file translation to Kubernetes Ingress for nginx like traffic routing to services within the kubernetes cluster

But Ingress has it's gotchas that can waste days of your time in order to have Nginx like Context Switch between services within the cluster this article offer complete solution with the use of Ingress Annotations

Nginx Proxy pass enables traffic routing to different services under same domain like the image below

This split of services is the foundation of microservice application that is achevied with Nginx-Ingress in Kubernetes. To achieve this an Ingress Resource is to be created

The following is a sample Ingress resource that implements the above chart's request flow. This sort of an example can be found at many joints in the internet

But They don't reveal the secret

0%
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: main-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "cluster-issuer-production"
      spec:
        tls:
        - hosts:
          - example
          secretName: tls-production-key
        rules:
        - host: example.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: front-main
                  servicePort: 3000

              - path: /api/web-engine/
                backend:
                  serviceName: /api/flask-engine/
                  servicePort: 80

              - path: /auth/
                backend:
                  serviceName: auth-server
                  servicePort: 80
    

Here's what does WORK

Look at the modified example

     apiVersion: networking.k8s.io/v1beta1
     kind: Ingress
     metadata:
       name: main-ingress
       annotations:
         kubernetes.io/ingress.class: "nginx"
         cert-manager.io/cluster-issuer: "bs-cluster-issuer-production"
         # Wazza
         nginx.ingress.kubernetes.io/rewrite-target: /$1
     spec:
       tls:
       - hosts:
         - example.com
         secretName: tls-production-key
       rules:
       - host: example.com
         http:
           paths:
             - path: /?(.*) # Notice the strange regex?
               backend:
                 serviceName: frontend
                 servicePort: 3000

             - path: /api/flask-engine/?(.*) # Notice the strange regex at the end of the specified route?
               backend:
                 serviceName: flask-server
                 servicePort: 80
     ---

   

Introducing Ingress Annotations

As the Irish guy(whose name I can't remember) who is in the core developer cirle of Ingress for kubernetes said 90% of all networking config can be achieved with Ingress, the complete context switch is possible too

The generic example of Ingress resource available on kubernetes.io only does a basic routing to services

In case of api server, the url mentioned in the Ingress resource must exactly match the "path" of Ingress and also the static files shall be unaccessible

The Anwser is ingress annotation : rewrite-target

nginx.ingress.kubernetes.io/rewrite-target: /$1

The $1 is basically the first set of characters that appear in this """ ?(.*) """ expression i.e all the characters after end of path declaration in Ingress

And with rewrite-target we send the captured strings straight to the / of every service where ?(.*) is present

      www.example.com/api/flask-server/static redirects_to----> flask-server/static # The solution your looking for
   

instead of

     www.example.com/api/flask-server/static redirects_to----> flask-server/api/flask-server/static # This obviously fails and you are sad. Try it out on a server in your local Machine to be 404ed for good
   

Summary (assuming you didn't like my long story)

Add this Annotation to Your Kubernetes Ingress

     metadata:
       annotations:
          nginx.ingress.kubernetes.io/rewrite-target: /$1
   

Add this regex to path declaration ?(.*) Example:

      - path: /your-strange-path/?(.*) # The strange regex
   

Boooom your Nginx ProxyPass has transformed into Kubernetes-Ingress route

PUTT ADD HERE