skip to Main Content

I am working on a new Kubernetes cluster setup. This setup will have about 25 microservices hosted in 25 different pods. These will be exposed via 25 different NodePort services. To access them from outside, I’m trying to integrate nginx ingress with a NLB(Note: all of this setup is hosted in AWS EKS)
Now, the microservices uses swagger which means there is redirection in the URL.

For e.g: https://example.com/customerservice ->
https://example.com/swagger/index.html (customerservice svc->pod)
https://example.com/orderservice ->
https://example.com/swagger/index.html (orderservice svc->pod)

So on and so forth for the rest of the 23 services

The services work for the info or healthpoint if I enter the whole URL like below:

https://example.com/orderservice/v3/info

https://example.com/customerservice/v3/healthcheck

The above endpoints works fine if I enter the whole URL manually. However, the users will expect to enter only https://example.com/customerservice, and it should redirect to the respective swagger page like this https://example.com/swagger/index.html

Below is my ingress YAML file, which is working for whole URLs like a v3/info or healthcheck, but not doing the redirection properly.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
  labels:
    app: trial-ingress
  name: trial-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: customerservice-svc
            port:
              number: 80
        path: /customerservice(/|$)(.*)
        pathType: Prefix
      - backend:
          service:
            name: orderservice-svc
            port:
              number: 80
        path: /orderservice(/|$)(.*)
        pathType: Prefix

If I use the above ingress and try to load https://example.com/customerservice then it redirects me to https://example.com/swagger/ which means it is trying to redirect in the correct direction but only takes in one argument/word (swagger) and removes rest of the string which then gives a 404 error

Expected Result: When user tries to load https://example.com/customerservice it should redirect to https://example.com/swagger/index.html page of the customerservice pod and similarly for all other services

2

Answers


  1. To handle redirections in nginx ingress for a Kubernetes cluster hosting microservices with Swagger, you need to set up your ingress rules to properly redirect requests to the appropriate Swagger documentation URL.

    That means updating the rewrite-target annotation to redirect to the swagger index.html.
    And then add custom logic using more advanced nginx configurations, done with the nginx.ingress.kubernetes.io/configuration-snippet annotation, which adds custom configurations to the Location configuration block (as mentioned here).

    Your Ingress YAML would be:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /swagger/index.html
        nginx.ingress.kubernetes.io/use-regex: "true"
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/configuration-snippet: |
          rewrite ^(/customerservice)$ $1/ redirect;
          rewrite ^(/orderservice)$ $1/ redirect;
          # Add similar rewrite rules for other services
      labels:
        app: trial-ingress
      name: trial-ingress
    spec:
      ingressClassName: nginx
      rules:
      - host: example.com
        http:
          paths:
          - backend:
              service:
                name: customerservice-svc
                port:
                  number: 80
            path: /customerservice(/|$)(.*)
            pathType: Prefix
          - backend:
              service:
                name: orderservice-svc
                port:
                  number: 80
            path: /orderservice(/|$)(.*)
            pathType: Prefix
          # Add paths for other services
    

    That would rewrite requests from https://example.com/customerservice to https://example.com/customerservice/swagger/index.html (specific to the customer service), and similarly for other services.

    You would get:

     ┌─────────────┐       ┌─────────────┐       ┌─────────────────────┐
     │             │       │             │       │                     │
     │    User     │──────►│     NLB     │──────►│  NGINX Ingress      │
     │             │       │             │       │                     │
     └─────────────┘       └─────────────┘       └─────────────────────┘
                                                               │
                                                               │
                                                               ▼
     ┌───────────────────────────────────────────────────────────────────┐
     │                               Microservices in Pods               │
     │                                                                   │
     │   /customerservice ────────────► (Customer Service Pod Swagger)   │
     │                                                                   │
     │   /orderservice    ────────────► (Order Service Pod Swagger)      │
     │                                                                   │
     │                                  (Other Services)                 │
     └───────────────────────────────────────────────────────────────────┘
    

    (To be tested in a staging environment first, before deploying it to production!)

    Login or Signup to reply.
  2. You can try the following YAML file if it helps:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-demo
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/use-regex: "true"
        nginx.ingress.kubernetes.io/rewrite-target: /$3
        nginx.ingress.kubernetes.io/x-forwarded-prefix: /$1
    spec:
      rules:
      - host: example.com
        http:
          paths:
          - path: /()()(.*)
            pathType: Prefix
            backend:
              service:
                name: customerservice-svc
                port:
                  number: 80
          - path: /orderservice(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: orderservice-svc
                port:
                  number: 80
    

    You can also read related threads on this link.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search