As we all know what Kubernetes has to offer in the containers and microservices ecosystem. In this blog post we will look at Istio which is a service mesh that helps in securing, connecting and observing your microservices running in your Kubernetes cluster. Now, don’t get overwhelmed by all the terms that I have thrown above. If you do not understand them, you will be by the end of this blog post.

Prerequistites

What is Istio?

Your microservices application have many components each interacting with each other. This network of all the components form a service mesh.
As a service mesh grows in size and complexity, it can become harder to understand and manage. Its requirements can include discovery, load balancing, failure recovery, metrics, and monitoring. A service mesh also often has more complex operational requirements, like A/B testing, canary rollouts, rate limiting, access control, and end-to-end authentication.

Istio helps us with all the above challenges and the biggest advantage is you will get all the below features without having to instrumenting your application ( in simple words without adding a single line of code into your application):

  • Traffic Management: Istio’s easy rules configuration and traffic routing lets you control the flow of traffic and API calls between services. Istio simplifies configuration of service-level properties like circuit breakers, timeouts, and retries, and makes it a breeze to set up important tasks like A/B testing, canary rollouts, and staged rollouts with percentage-based traffic splits.
  • Security: Istio’s security capabilities free developers to focus on security at the application level. Istio provides the underlying secure communication channel, and manages authentication, authorization, and encryption of service communication at scale. With Istio, service communications are secured by default, letting you enforce policies consistently across diverse protocols and runtimes – all with little or no application changes.
  • Observability: Istio’s robust tracing, monitoring, and logging features give you deep insights into your service mesh deployment. Istio uses jaeger, prometheus and grafana to provide us with this feature.

Now we will not dive into the architecture of Istio because that can take a whole blog of it’s own to get addressed. You can learn more from Istio Documentation. Still, we will cover the basics that are required to understand how everything works in Istio.

Istio Architecture

An Istio service mesh is logically split into a data plane and a control plane.

  • The data plane is composed of a set of intelligent proxies (Envoy) deployed as sidecars. These proxies mediate and control all network communication between microservices along with Mixer, a general-purpose policy and telemetry hub.
  • The control plane manages and configures the proxies to route traffic. Additionally, the control plane configures Mixers to enforce policies and collect telemetry.
Istio Architecture

You can watch the below video if you are interested to dive deeper into what happens inside of Istio during routing of a request. If not, you can move on. But I highly recommend you watch this video to gain a deep knowledge of Istio.


Istio – The Packet’s-Eye View – Matt Turner

Installation

I am using a Kubernetes Cluster which is set up in AWS using kops. But the below should be applicable on any Kubernetes Cluster. Follow the below commands to install Istio:

curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.1.0 sh -
cd istio-1.1.0
export PATH=$PWD/bin:$PATH
for i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i; done
kubectl apply -f install/kubernetes/istio-demo.yaml

Verify that Istio has been installed successfully by running the below commands:

kubectl get svc -n istio-system
kubectl get pods -n istio-system

You should see all the Istio components in Running state.

Few Important Concepts of Istio

Lets briefly look at some of the concepts of Istio without which nothing will make sense at all.

Gateway: A Gateway configures a load balancer for HTTP/TCP traffic operating at the edge of the mesh, most commonly to enable ingress traffic for an application. A Gateway can be more simplified as a gatekeeper or a gate. This allows only a specific type of traffic to come in.

Virtual Service: A Virtual Service defines the rules that control how requests for a service are routed within an Istio service mesh. For example, a virtual service could route requests to different versions of a service or to a completely different service than was requested. We will always use a virtual service whenever we will do traffic shifting.

Destination Rules: A Destination Rule configures the set of policies to be applied to a request after Virtual Service routing has occurred.

This is a great post describing the above concept with much more simplicity and detail.

Application Setup

To demonstrate how weight based routing is configured we need an application. We will use the sample bookinfo application provided by Istio for learning how weight based routing is done. Below is the architecture of the application:

  • It has a product page which will serve as the entry point of the application.
  • It has a details component which is made in Ruby and serves the details about a particular book.
  • It also has a reviews component which has 3 versions. v1 corresponds to no stars, v2 corresponds to black stars and v3 corresponds to red stars.
  • The reviews component talks to ratings section which is made in nodejs to fetch ratings.
  • Also in every Pod, there is a separate container for Envoy proxy which is responsible for the routing of the requests to the main app container.
BookInfo Application Architecture

Lets deploy the application by running the below commands:

kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
kubectl get deployments
kubectl get pods

A very important thing to note here, You can see 2/2 in the Ready Column which specifies the number of containers inside a Pod. Here we have 2 containers, one containing Envoy proxy and the other containing the application. And also in the application architecture as explained earlier, you can see all the requests to the main container are going via Envoy.

Now to make this application available to the outside world we need a gateway. A gateway is similar to Ingress in Kubernetes. Follow the below command to configure a gateway:

kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

Since I am running the Kubernetes Cluster in AWS using kops the above will create a Load Balancer in AWS. In my case, the LoadBalancer is exposed using hostname but in other cloud providers like Azure or Google, it’s in the form of IP address. To know the URL of the LoadBalancer run the below command:

// if LoadBalancer is exposed using hostname run the below command
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
// if LoadBalancer is exposed using IP run the below command
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')

Set GATEWAY_URL:

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Confirm that the app is running by running the below command:

curl -s http://${GATEWAY_URL}/productpage | grep -o "<title>.*</title>"

Apply the destination rules:

kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

You can display the destination rules with the following command:

kubectl get destinationrules -o yaml

To learn more visit the Traffic Management section of Istio Docs.

If you go to your browser and paste the url of the gateway followed by productpage. You can get this by running echo $GATEWAY_URL For Eg: http://a0eb8218a140f11e99aeb0257da0d5cd-458366803.ap-south-1.elb.amazonaws.com/productpage, you should see the below page and if you refresh the page you should see all the 3 versions of ratings app i.e. with no stars, black stars and red stars.

Bookinfo Application with Reviews v2

Weight Based Routing

Now that our application is setup it’s time to play with shifting traffic from one version of the application to another. We call this weight based routing or canary deployments where we send a small portion of traffic to the newer version of the application while keeping most of the traffic to older version to test how newer application reacting in production and once everything is okay we slowly route all the traffic to this newer version. This has lots of advantages, we can see how our newer application is performing without having to worry about any critical issues because if the new code is generating any issue we can rollback effortlessly to the previous version without any downtime and we can also observe how the users are reacting to the newer version of the code.

Currently the reviews component of our application has 3 versions. We will first distribute the traffic between version 1(no stars) and version 3(red stars) and after that we will fully send all the traffic to version 3.

Copy and paste the below code to shift 50 percent of traffic to version 1 and 50 percent of traffic to version 3 of reviews component.

kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

If you look into the yaml file you will see that in the specifications sections we have two destinations v1 and v3 and the weight is 50 for each of the versions.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50

Now if you go to your browser and hit refresh multiple times you will only see version 1 with no stars and version 3 with red stars.

Now lets assume that version 3 of reviews app is stable so we wil send all the traffic to version 3 of reviews component. To do this copy and paste the below code:

kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml

Now if you go to your browser and no matter how many times you hit refresh you will only see version 3 of reviews application that is with red stars. This is happening because when you will look into the yaml file you see that we have instructed Istio to send 100 percent of traffic to version 3 of reviews application.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v3

There are many more things that we can do with Istio for example mutual TLS to secure the communication between your microservices application, tracing, monitoring, circuit breaking, timeouts, retries and the list goes on.

Hope you have gained some understanding of what is Istio and the rich set of features that it offers. Feel free to let me know in the comments if you face any challenges, I will be more than happy to help.

Leave a comment

Your email address will not be published. Required fields are marked *