Ingress is not working for application gateway ingress controller (AGIC) add-on of AKS

Viewed 2704

I enabled AGIC in the Azure portal and then created Fanout Ingress. But it's not working. I checked Rules (ingress-appgateway > Rules > Path-based routing) and paths are targeting correct backend pool.

When I am testing health probe, it's failing ("MC_..." resource group > ingress-appgateway > Health probes > Click test) - showing error :

One or more of your backend instances are unhealthy. It is recommended to address this health issue first before attaching the probe

I tried:

  • disabling and enabling AGIC -> did not work
  • using pathType: ImplementationSpecific (instead of pathType: Prefix) -> did not work
  • nginx.ingress.kubernetes.io/rewrite-target: /$1 & /foo(/|$)(.*) -> did not work

At the top of the Overview page of "ingress-appgateway" (Azure portal), showing error:

All the instances in one or more of your backend pools are unhealthy. This will result in a 502 error when you try to access your application hosted behind the Application Gateway. Please check the backend health and resolve the issue.

It works only If I remove paths (/foo & /bar) and target a single service.

FYI, I am using Azure CNI networking and existing VNet (dedicated subnet).

deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: demo-web-app1
  namespace: demo
spec:
  selector:
    app: demo-web-app1
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 4200
    targetPort: 80
    
---

apiVersion: v1
kind: Service
metadata:
  name: demo-web-app2
  namespace: demo
spec:
  selector:
    app: demo-web-app2
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-web-app1
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo-web-app1
  template:
    metadata:
      labels:
        app: demo-web-app1
    spec:
      containers:
      - name: demo-web-app1
        image: myacr.azurecr.io/myacr6472:375
        ports:
        - containerPort: 80
        
---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-web-app2
  namespace: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo-web-app2
  template:
    metadata:
      labels:
        app: demo-web-app2
    spec:
      containers:
      - name: demo-web-app2
        image: myacr.azurecr.io/myacr6472:375
        ports:
        - containerPort: 80

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-demo-web-app
  namespace: demo
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /foo
        pathType: Prefix
        backend:
          service:
            name: demo-web-app1
            port:
              number: 4200
      - path: /bar
        pathType: Prefix
        backend:
          service:
            name: demo-web-app2
            port:
              number: 8080
2 Answers

appgw.ingress.kubernetes.io/backend-path-prefix: / solved the problem as pointed out by @Matt in the comment section.

I can now target multiple backend pools using different paths i.e. /api for API service & /app for UI app.

I wrote an article in my site about serving multiple APIs

Using appgw.ingress.kubernetes.io/backend-path-prefix: "/" We will be able to specify multiple rules.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gateway-ingress
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
  rules:
  - http:
      paths:
      - path: /service1/*
        pathType: Prefix
        backend:
          service:
            name: k8-boot-graphql-rest-aks-apm-test
            port:
              number: 8081
      - path: /service2/*
        pathType: Prefix
        backend:
          service:
            name: k8-sboot-restapi-test
            port:
              number: 8080

http://host/service1/actuator/health ---> Microservice 1
http://host/service2/actuator/health ---> Microservice 2

Sample deployment script I have used

apiVersion: v1
kind: Pod
metadata:
  name: k8-boot-graphql-rest-aks-apm-test
  labels:
    app: k8-boot-graphql-rest-aks-apm-test
spec:
  containers:
  - image: sreyasvpariyath/k8-boot-graphql-rest-aks-apm-test:latest #CHANGE
    imagePullPolicy: Always
    name: k8-boot-graphql-rest-aks-apm-test
    ports:
    - containerPort: 8081
      protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: k8-boot-graphql-rest-aks-apm-test
spec:
  selector:
    app: k8-boot-graphql-rest-aks-apm-test
  ports:
  - protocol: TCP
    port: 8081
    targetPort: 8081
Related