Search code examples
kubernetesgrpcazure-aksistionginx-ingress

Kubernetes ingress controller with Istio


I have a GRPC application (.NET app) deployed in Azure K8 Cluster using bitnami asp.net code helm chart. I am passing following values to chart.

aspnet-core:
  fullnameOverride: app-name
  image:
    registry: registrypath
    repository: repopath
    tag: latest
    pullPolicy: Always
 
  args: 
    - Service.dll

  bindURLs: http://+:5010;https://+:7010       
  service:
    type: ClusterIP
    ports:
      http: 7010

  containerPorts:
    http: 7010

  ingress:
    enabled: true
    pathType: Prefix
    hostname: host.domain.com
    path: /
    annotations:
      nginx.ingress.kubernetes.io/backend-protocol: "GRPCS"
      nginx.ingress.kubernetes.io/ssl-redirect: "true"
    tls: true
    ingressClassName: "nginx"

This app is exposed using Kubernetes ingress nginx. Once accessed from outside, I was able to reach out to endpoint.

However, after installing Istio, I am unable to reach out to endpoint. I tried following Istio documentation and created a new ingressClass "istio" and used it in ingress configuration (ingressClassName: istio) but still not able to reach out to endpoint and getting an error "404 Not Found nginx"

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: istio
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
spec:
  controller: istio.io/ingress-controller

While looking at ingress controller logs, I am seeing below error

I0412 02:00:10.148428       7 store.go:578] "ignoring ingressclass as the spec.controller is not the same of this ingress" ingressclass="istio"
W0412 02:01:59.300315       7 controller.go:331] ignoring ingress <serviceName> in <NAMESPACE> based on annotation : no object matching key "istio" in local store
I0412 02:01:59.300359       7 main.go:107] "successfully validated configuration, accepting" ingress="<NAMESPACE>/<SERVICENAME>"
I0412 02:01:59.307387       7 store.go:489] "removing ingress because of unknown ingressclass" ingress="<NAMESPACE>/<SERVICENAME>"

Any suggestion or idea what configuration am I missing? I am relatively new to Istio and so far trying to avoid istio ingress gateway as most of the apps (except GRPC app) are working as expected.


Solution

  • To expose your GRPC application in an Azure Kubernetes cluster using Istio instead of NGINX Ingress, you need to set up Istio's own Gateway and VirtualService resources. These resources direct traffic from the edge of the mesh into your service within the mesh. Make sure Istio is installed in your cluster and that automatic sidecar injection is enabled for your namespace (if it's not the default).

    kubectl label namespace your-namespace istio-injection=enabled
    

    In my case it is enter image description here

    therefore, need to define a Gateway in the aks-istio-ingress namespace, which will manage the ingress traffic

    Grpc gateway example

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: grpc-gateway
      namespace: aks-istio-ingress  # Use the namespace where the Istio ingress is running
    spec:
      selector:
        istio: ingressgateway-external-asm-1-20  # Use the correct selector for your external gateway
      servers:
      - port:
          number: 7010
          name: grpc
          protocol: GRPC
        hosts:
        - "host.domain.com"
    

    modify the host with your own value. Ensure that the actual value you are replacing for the placeholder host.domain.com has a DNS A record pointing to the external IP 4.236.238.18 (your own external IP) of your Istio ingress gateway.

    next is VirtualService which will direct the traffic from the Gateway to the specific service in the cluster.

    Grpc Virtual service example

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: grpc-virtualservice
      namespace: aks-istio-ingress  # Ensure this is the same namespace as your service
    spec:
      hosts:
      - "host.domain.com"
      gateways:
      - grpc-gateway
      http:
      - match:
        - uri:
            prefix: "/"
        route:
        - destination:
            host: app-name.aks-istio-ingress.svc.cluster.local  # Adjust this to your service's DNS name
            port:
              number: 7010
    
    

    apply them

    kubectl apply -f grpc-gateway.yaml
    kubectl apply -f grpc-virtualservice.yaml
    

    enter image description here

    Validate the Deployment and the service

    kubectl get gateway -n aks-istio-ingress
    kubectl get virtualservice -n aks-istio-ingress
    kubectl get svc -n aks-istio-ingress
    

    enter image description here

    Now assuming that your .NET application is ready to handle GRPC traffic on port 7010 and that you have configured your application to run in the appropriate namespace. Just adjust the service names and namespaces as necessary to fit your actual deployment details.