0
votes

I'm using kubernetes nginx ingress controller (not the nginx supported one, but the k8s supported one), with AKS (k8s version 1.17 at the moment), for which the corresponding apiversion for Ingress is networking.k8s.io/v1beta1, therefore using this documentation.

For the most basic Ingress, all fine, i.e:

# singlebackend-ingress-rule.yaml
apiVersion: networking.k8s.io/v1beta1 #  AKS is with 1.17, and supports only apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-rules
spec:
  rules:
  - host: ingress-domain.westeurope.cloudapp.azure.com
    http:      
      paths:
      - backend:
          serviceName: backend-webapi
          servicePort: 80

Deployed as:

kubectl apply -f singlebackend-ingress-rule.yaml

curl http://ingress-domain.westeurope.cloudapp.azure.com.westeurope.cloudapp.azure.com/health
200
{                                                         
   "me" : {                                               
      "status" : "ok",                                    
      "version" : "v15",                                  
      "appName" : "Backend.WebApi",  
      "aspNetCore_Environment" : "aks"                    
   }                                                      
}                                                         

However, if I only add backend: /api, and do the exact same:

# multiplebackend-ingress-rule.yaml
apiVersion: networking.k8s.io/v1beta1 #  AKS is with 1.17, and supports only apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-rules
spec:
  rules:
  - host: ingress-domain.westeurope.cloudapp.azure.com
    http:      
      paths:
      - backend:
          serviceName: backend-webapi
          servicePort: 80
        path: /api

Deployed as:

kubectl apply -f multiplebackend-ingress-rule.yaml

curl http://ingress-domain.westeurope.cloudapp.azure.com.westeurope.cloudapp.azure.com/api/health

HTTP/2 404
server: nginx/1.19.1
date: Tue, 01 Sep 2020 09:24:36 GMT
content-length: 0
strict-transport-security: max-age=15724800; includeSubDomains

I get 404. What am I missing?

2

2 Answers

2
votes

Your defined route is /health not /api/health.

The path you define in your Ingress, must be handled by your back-end server.

Your Ingress sends all your requests prefixed with /api to your service backend-webapi, but it doesn't discard the path /api from the route itself.

So, when you send request to http://ingress-domain.westeurope.cloudapp.azure.com.westeurope.cloudapp.azure.com/api/health, your service must handle /api/health not /health.

1
votes

By default nginx sends traffic to whatever is mentioned in path.You can use rewrite-target annotation to specify target URI where the traffic must be redirected.

# singlebackend-ingress-rule.yaml
apiVersion: networking.k8s.io/v1beta1 #  AKS is with 1.17, and supports only apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-rules
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress-domain.westeurope.cloudapp.azure.com
    http:      
      paths:
      - backend:
          serviceName: backend-webapi
          servicePort: 80
        path: /api

As an alternative to rewrite-target you could use app-root annotation

# singlebackend-ingress-rule.yaml
apiVersion: networking.k8s.io/v1beta1 #  AKS is with 1.17, and supports only apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-rules
  annotations:
    nginx.ingress.kubernetes.io/app-root: /
spec:
  rules:
  - host: ingress-domain.westeurope.cloudapp.azure.com
    http:      
      paths:
      - backend:
          serviceName: backend-webapi
          servicePort: 80
        path: /api

With above change below curl should work without needing to have a http handler handling /api/health in the backend. You can simply have a http handler at /health

curl http://ingress-domain.westeurope.cloudapp.azure.com.westeurope.cloudapp.azure.com/health