Istio step-by-step Part 04 — Traffic routing path of Istio service-mesh (Ingress routing)

Hi! Welcome back to my Istio step-by-step tutorial series. This tutorial contains two parts as Part A-Ingress traffic routing and Part B-Egress traffic routing. Let’s take a look about Ingress traffic routing.

In my last tutorial, I explained how to deploy an application and invoke the service. But I didn’t explain much about traffic routing. So, I thought to do another tutorial in two parts to explain traffic routing in the service mesh. As the whole content is too much and bit complex I thought to split it into two parts as,

  • Ingress Traffic (Part A)
  • Egress Traffic (Part B)

Ingress Traffic is the traffic which comes to the service mesh. The traffic is originated in the outside and proceeds toward a destination inside of the service mesh.

You know in Kuberenetes there is an Ingress Controller to control all the ingress traffic. But when it comes to Istio, Ingress controller is replaced with two components named, Gateway and VirtualService. Gateways are used to configure the istio-proxies (envoys) while the VirtualServices are used to route the traffic. Let’s check about these two in more details.

Gateways

A Gateway can be more simplified as a gatekeeper or a gate. This allows only a specific type of traffic to come in. Let’s take an example. Below is the Gateway rule which I used in the previous tutorial.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

Here, under spec (specifications).servers.port.number is 80 and the name is http. That means I have configured the envoys to allow all the traffic with HTTP protocol to the port 80.

Now let’s take a deep dive. Under spec.selector.istio is ingressgateway. Basically, istio-ingressgateway pods are labelled with “istio=ingressgateway”. You can check it by running following commands.

kubectl get pods -n istio-system #to get the pods with namespace istio-system
kubectl describe pod <pod_name (istio-ingressgateway-...)> #to describe the pod

Here you can see what I explained earlier. So, according to my gateway rule, the configurations are actually applied for istio-ingressgateway pod.

Well, now the port 80 is ready with the traffic. Next, we need a VirturalService to route this traffic.

VirtualService

This led the path for traffic to move. Let’s take the same example.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: "helloworldservice"
spec
:
hosts:
- "*"
gateways
:
- helloworld-gateway
http:
- match:
- uri:
exact: /helloworld
route:
- destination:
host: "helloworldservice"
port
:
number: 9095

If you check the name of the Gateway, it is helloworld-gateway. So, we use it to connect the Gateway and the Virtualservice with each other. You can see in the Virtualservice, under spec.gateways I have mentioned the name of our gateway. That is the place where these two are connecting with each other. Basically what happens in the Virtualservice is, when the traffic starts flowing through the gateway, this redirects all of it to our service port (here my service port is 9095). This happens with spec.http.route.destination.port.number

Photo credit: https://www.salzberginsurance.com/img/~www.salzberginsurance.com/1370143_66842063.jpg

Now let’s take a look how to invoke the service.

To invoke our service from outside of the service mesh we need an ingress port and an ingress host. In my service, I use NodePort as the service type because I want to expose my service to the outside.

I am not going to describe here about NodePort, ClusterIP and LoadBalancer, you can refer for more details about those through this article Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what? by Sandeep Dinesh.

To invoke the service first, we have to determine the ingress port of the HTTP traffic. To do that execute the following command. The command means get the service istio-ingressgateway under the namespace istio-system.

kubectl get svc istio-ingressgateway -n istio-system

There you will get a set of ports as;

80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:32243/TCP,8060:31504/TCP,853:32380/TCP,15030:30112/TCP,15031:32472/TCP

Here, the ingress port of port 80 is 31380. If you had referred the previous tutorial you could remember that we use the port 31380 to invoke our service.

As our cluster is running in Minikube, we use minikube IP as the ingress host to access the service.

curl http://192.168.99.100:31380/helloworld

The summary of the ingress traffic routing

  1. Invoke the service through the ingress port (sending traffic inside).
  2. The traffic is captured by Istio and through iptables traffic is routed to port 80.
  3. Port 80 is exposed for HTTP traffic. It allows the traffic routing to Virtualservice
  4. Virtualservice redirects the traffic to the destination port and hits the service

This is all for this tutorial and hope you could understand the basic scenario happens. Keep in touch to learn more. See you soon with the next part of the tutorial. Thank you.

<< Previous tutorial

Next tutorial>>