fortanu82
fortanu82

Reputation: 471

Azure AKS | Application gateway | Ingress | Backend Prefix

I am bit confused the way path resolves the endpoint, does it show in any logs the final endpoint it creates. I am stuck with this now. Below is the endpoint which I wanted to call:-

https://hostname/api/orders/employees. And to call this endpoint through Ingress application gateway, this is how I configured but it always return 502 bad gateway error.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ordersapi
  namespace: orders
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: orders.apps.com
    http:
      paths:
      - path: /api/orders/employees
        backend:
          serviceName: orderservice
          servicePort: 80

Upvotes: 1

Views: 5812

Answers (6)

Mithras
Mithras

Reputation: 1

For me the solution was to just add "*" to paths, e.g.

  rules:
    - http:
        paths:
          - pathType: Prefix
            path: /api/*
            backend:
              service:
                name: api
                port:"
                  number: 80
          - pathType: Prefix
            path: /graphql*
            backend:
              service:
                name: api
                port:
                  number: 80

without any extra annotations. For whatever reason it does not work without "*" at the end.

Upvotes: 0

Szymon Kropisz
Szymon Kropisz

Reputation: 11

I got same issue. My ingress setup was like:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  rules:
  - host: <myhostname>
    http:
      paths:
      - path: /api*
        backend:
          serviceName: backend-app
          servicePort: 80
      - path: /
        backend:
          serviceName: frontend-app
          servicePort: 80

If I defined path like /api/todolist, the endpoint worked fine. On the other hand if I went with /api* my requests were redirected to frontend app.

The problem was that endpoint /api/todolist existed on my backend and returned status was 200, for the /api endpoint I did not setup anything so I got 404 status.

In my case I needed to add healthcheck under /api edpoint, that returned proper http status :) For me returning string "Healthy" was enough.

Upvotes: 1

fortanu82
fortanu82

Reputation: 471

Finally, there are two solution to this problem:-

First

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ordersapi
  namespace: orders
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: orders.apps.com
    http:
      paths:
      - path: /api/orders/employees
        backend:
          serviceName: orderservice
          servicePort: 80
      - path: /api/product/products
        backend:
          serviceName: orderservice
          servicePort: 80h

Second

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ordersapi
  namespace: orders
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/backend-path-prefix: "/api/"
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: orders.apps.com
    http:
      paths:
      - path: /api/*
        backend:
          serviceName: orderservice
          servicePort: 80

Upvotes: 2

fortanu82
fortanu82

Reputation: 471

Defining multiple paths without backend-path-prefix worked, e.g. http: paths: path: /api/order/employees backend: serviceName: orderservice servicePort: 80 path: /api/position/members backend: serviceName: positionservice servicePort: 80

This seems to be a complex way but so far I found this the only way which worked.

Upvotes: 0

fortanu82
fortanu82

Reputation: 471

@djsly @Jean-Philippe Bond - Thanks for your response and pointing the URL that helped me to investigate further. Having the backend application deployed on port 80 had a reason as SSL terminates at application gateway and listener redirects the request to backend application running on port 80, which works fine.

After further investigation, I added backend path prefix in ingress file (appgw.ingress.kubernetes.io/backend-path-prefix: "/api/orders/employees") which resolved the problem for one endpoint but not for all.

To describe the problem in details, application contains some of the restful services mentioned below and their endpoints are such as -

http://hostname/api/orders/employees http://hostname/api/Lookup/officeHierarchy http://hostname/api/Department/codes http://hostname/api/position/members

Now if you see, these different endpoints starts with prefix "/api/" and then the controller name and actions.

Here Expected Result is If any of these endpoints are called (via HTTP Get), data should be returned but it fails.

Investigation done so far I added the prefix and did some changes to it. Thus If I configure my ingress like below, it returns the result successfully for only one specific endpoint - >

curl -v http://orders.apps.com/api/orders/employees returns 200 but fails for others.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ordersapi
  namespace: orders
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/backend-path-prefix: "/api/orders/employees"
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: orders.apps.com
    http:
      paths:
      - path: /api/orders/employees
        backend:
          serviceName: orderservice
          servicePort: 80

Thus , to make all endpoints works, I did the below changes in the above mentioned ingress file but calling curl -v http://orders.apps.com/api/orders/employees returns 404. And the same goes with other endpoints like curl -v http://orders.apps.com/api/department/codes returns 404.

As per my understanding, by doing the below changes - "path - /api/*" should be overwritten to the path - /api/orders/employees being called but it does not.


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ordersapi
  namespace: orders
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/backend-path-prefix: "/api/"
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: orders.apps.com
    http:
      paths:
      - path: /api*
        backend:
          serviceName: orderservice
          servicePort: 80

Your suggestions are appreciated. Thanks

Upvotes: 0

djsly
djsly

Reputation: 1628

You seem to have enabled SSL redirect but your service is serving on a non ssl port.

this could explain the bad gateway.

Often, the Azure AppGW will return 502 Bad Gateway when there are bad Certs involved, the health check for the backend service is wrong, and other reason

You should look at this:

https://support.microsoft.com/en-ca/help/4504111/azure-application-gateway-with-bad-gateway-502-errors

and this

https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-troubleshooting-502

Upvotes: 1

Related Questions