Implementing Istio in a Kubernetes cluster
Tags: kubernetes, devops, observability
Published: 2021-10-25 13:22:34

_As the complexity of a microservice architecture grows, it becomes important to implement a service mesh for better insights into your cluster and microservices. In this blog, [Kristijan](https://www.linkedin.com/in/kristijan-mitevski/) explains how Istio can be used as a service mesh, along with a detailed installation steps & configuration setup._

Service Mesh? You’ve heard about it, but does it solve something, or is it just another hot buzzword in the industry?

In this article you will learn about the Istio service mesh, along with a full installation guide and configuration setup.

###**Table of contents**

- <a href="#istio">What is Istio?</a>
- <a href="#istio-architecture">Istio architecture</a>
- <a href="#installing-istio">Installing Istio</a>
- <a href="#observability">Observability</a>
- <a href="#demo-application">Demo application</a>
- <a href="#recap">Recap</a>

Before moving straight to Istio, it’s worth mentioning that in one of our previous articles - [The Age of Service Mesh](https://www.squadcast.com/blog/the-age-of-service-mesh), Gigi Sayfan explained in detail how service meshes work and what problems they solve.

I highly suggest you give that article a read. Maybe even as a prequel, as it will provide you with great insight into service mesh basics and the general idea behind them.

Right now, there are a plethora of options for service meshes.

To name a few:

- [Istio](https://istio.io/latest/)
- [Linkerd](https://linkerd.io/)
- [Traefik](https://traefik.io/traefik-mesh/)
- [Consul](https://www.hashicorp.com/products/consul/multi-platform-service-mesh)
- [Kuma](https://kuma.io/)

Each service mesh has its pros and cons, along with specific use cases that you should consider for your cluster and end goal.

You can decide which “brand” of a service mesh to install.

<h3 id="istio"><b>What is Istio?</b></h3>

Istio is a service mesh designed to enhance and give you better insight into your cluster and microservices.

One of the great things about Istio and service meshes overall is that they require absolutely no code change for them to work.

Istio works by integrating itself as an additional layer inside the Kubernetes cluster and thus provides modern features that you can utilize to your advantage.

Those features can include advanced load balancing, circuit breaking, mTLS traffic encryption, better authentication and authorization options, metrics, telemetry, and overall fine-grain control over the cluster’s traffic going in and out.

Now Istio isn’t just a single object that you install. It’s more of a collection of entities that work together and make up the whole service mesh.

Like Kubernetes, Istio has a control plane that manages everything and a data plane that handles the traffic between the services.

There is more to Istio, as it isn’t bound to only work in a Kubernetes cluster. It will also work with virtual machines and supports different deployment options both for installing and running.

In the next section, we will explain Istio’s components and architecture.

<h3 id="istio-architecture"><b>Istio Architecture</b></h3>

As the saying goes, a picture is worth a thousand words.

Consider the following diagram:

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61667c91616d7eecf473416f_image2.png)
<figcaption><a href="https://istio.io/latest/docs/ops/deployment/architecture/">Image Source</a></figcaption>

You can see that the traffic destined in and out of the pods doesn’t flow directly now; Instead, it first must pass through the sidecar proxies.

The container sidecars are Envoy proxies that get automatically injected into your pods on startup.

During installation, you instruct Istio which namespace to ‘watch’ and deploy Envoy proxies along with your applications.

You will see how this is done in action when we get to the installing section.

The other part is the control plane, made of multiple components bundled in one binary - [istiod](https://istio.io/latest/docs/ops/deployment/architecture/#istiod). The control plane manages the proxies, certificates, service discovery, and executing the configuration you set.

The components making Istio are:

- [Envoy](https://www.envoyproxy.io/)
- [Pilot](https://istio.io/v1.4/docs/ops/deployment/architecture/#pilot)
- [Citadel](https://istio.io/v1.4/docs/ops/deployment/architecture/#citadel)
- [Galley](https://istio.io/v1.4/docs/ops/deployment/architecture/#citadel)

To explain a bit better and give some analogy here.

Consider the service mesh as a telephone network.

The data plane consists of phones that you and your friends use to communicate with each other.

You will be able to communicate without them, but you will have to yell across. Instead, this way is much more modern, secure, and with better control over the communication.

Now the control plane will be the telephone service provider, and from there, all the calls get managed, routed, and billed.

Everything you apply is done towards and on the control plane; the control plane will communicate that change to the sidecar proxies.

The traffic traversing the data plane is only visible to the proxies; the other Istio components have no access.

<h3 id="installing-istio"><b>Installing Istio</b></h3>

Depending on your setup, Istio offers you different installation and [deployment strategies](https://istio.io/latest/docs/ops/deployment/deployment-models/).

Each cloud service provider has its own thing. So it’s best to go over the [platform setup](https://istio.io/latest/docs/setup/platform-setup/) and check if any prerequisites or dependencies are needed before installing.

The install options can range from using helm, istioctl, or using an operator.

You can look into them [at the following link](https://istio.io/latest/docs/setup/install/).

For this guide, we will install Istio using the `istioctl` tool.

First, you’ll need to download the binary:

```
$ curl -L https://istio.io/downloadIstio | sh -
```

Navigate into the newly created folder, export the path to the binary, and verify that it works:

```
$ cd istio-1.11.1/
$ export PATH=$PWD/bin:$PATH
$ istioctl version

no running Istio pods in "istio-system"
1.11.1
```

Well, that’s okay, you still haven’t installed Istio.

It is a good idea to run the pre-flight check to verify if your cluster doesn’t have any issues running the Istio service mesh.

```
$ istioctl x precheck

Install Pre-Check passed! The cluster is ready for Istio installation. 
```

Before moving forward, you should assess which type of profile you want Istio to be installed with.

There are six of them at the time of this writing:

- Default
- Demo
- Minimal
- External
- Empty
- Preview

You can view each profile with an extended description [here](https://istio.io/latest/docs/setup/additional-setup/config-profiles/).

We will go with the default profile intended for production environments.

Each profile is just a set of features that Istio will enable when installed.

If you want to test every feature, you can install it using the `demo` profile.

**Note:** Installing profiles that include the Ingress or Egress Gateway will automatically spin up an external load balancer.

Istio also offers customizations and custom third-party add-ons you can include in the profile.

Suppose none of the above profiles meet your requirements, you can [use istioctl to generate and create custom manifests](https://istio.io/latest/docs/setup/install/istioctl/#generate-a-manifest-before-installation) to fit your needs.

To install using the default profile:

```
$ istioctl install --set profile=default -y

✔ Istio core installed           	 
✔ Istiod installed                                                      	 
✔ Egress gateways installed  
✔ Ingress gateways installed
✔ Installation complete
```

Excellent! You’ve installed Istio successfully!

You are halfway there.

Now you will need to label which namespace Istio will control and inject sidecar proxies in the pods.

For example, to label the default namespace for sidecar injection:

```
$ kubectl label namespace default istio-injection=enabled

namespace/default labeled

```

You can now verify this with:

```
$ kubectl get ns --show-labels

NAME          	STATUS      AGE	     LABELS
default       	Active      119d     istio-injection=enabled
[other output truncated]
```

With that, you completed the Istio core components installation.

<h3 id="observability"><b>Observability</b></h3>

_I installed Istio, and now what?_

Next comes the observability part.

The Envoy proxies will send off telemetry and other data that you can use to visualize the traffic in the mesh.

Like the Prometheus and the Grafana setup, you will need Istio paired with a visualization tool to display the data.

You will use the [Kiali](https://kiali.io/) dashboard to visualize and see what’s going on in the cluster.

There is one caveat, however. Kiali requires that you have a running Prometheus instance in your cluster.

You can deploy one or supply the address of the existing one if you have it already deployed.

For simplicity and example purposes, the following section will use the demo manifests for deploying Kiali, [Jaeger](https://www.jaegertracing.io/), [Prometheus](https://prometheus.io/), and [Grafana](https://grafana.com/).

Keep in mind that you shouldn’t rely on this setup for running in production environments!

Further below, there will be an explanation of how to set up Kiali to work with an existing Prometheus instance.

####**Installing the Kiali dashboard**

Navigate to the Istio folder and apply the manifests located under `samples/addons`:

```
$  kubectl apply -f samples/addons
```

Applying the above will deploy many objects, so give them a couple of minutes to start.

Check on the Kiali pod if it’s started:

```
$ kubectl -n istio-system get pods -l app=kiali

NAME                           READY    STATUS	  RESTARTS      AGE
kiali-787bc487b7-fbxwm   	   1/1 	    Running   0             2m10s
```

Once it’s running, you can now access the dashboard using `kubectl` and `port-forward`.

However, `istioctl` offers a much simpler way:

```
$ istioctl dashboard kiali

http://localhost:20001/kiali 
```

open http://localhost:20001/kiali in your browser.

As you can see, there is no traffic running in the selected namespace, and Kiali will show no connections.

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616684f1618edf702efa6eba_image4.png)

If you want to access the other dashboards - Grafana and Jaeger, you can again use `istioctl dashboard`:

```
$ istioctl dashboard grafana
```

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/6166859af9a3b12e27b0ffbb_image7.png)

```
$ istioctl dashboard jaeger
```

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616685e77fab1b7f6fc90b66_image5.png)

####**Kiali tips**

There are also other ways to deploy Kiali that are more inclined to production use, where you can customize and set your own parameters.

Installing Kiali can be done by deploying the [Kiali-server](https://kiali.io/documentation/v1.39/installation-guide/#_kiali_only_install) or the [Kiali-operator](https://kiali.io/documentation/latest/installation-guide/#_helm_chart).

You can find the GitHub link for both Helm charts [here](https://github.com/kiali/helm-charts).

As mentioned in the previous section, you can specify external instances of Prometheus and the other tools.

It’s best to install all the tooling Kiali needs for you to have the most benefit and greater observability in the service mesh.

Those are the Prometheus instance, Grafana, and Jaeger for tracing.

**Note:** Refer to the Jaeger documentation as it requires additional configuration to have full distributed tracing in your apps.

Grafana and Jaeger are optional for Kiali and not required for it to work.

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/616686624a51663a95303cf7_image6.png)
<figcaption><a href="https://kiali.io/documentation/latest/architecture/">Image Source</a></figcaption>

You can specify every connection to the other systems during installation.

Example, for specifying an [existing Prometheus instance](https://kiali.io/documentation/v1.36/runtimes-monitoring/#_using_another_prometheus_instance):

```
$ helm install kiali-server kiali-server --repo https://kiali.org/helm-charts \
  -n istio-system \
  --set auth.strategy="anonymous" \
  --set external_services.custom_dashboards.prometheus.url="http://prometheus-k8s.monitoring:9090/" \
  --set external_services.prometheus.url="http://prometheus-k8s.monitoring:9090/"
```

The Kiali authentication options are available [here](https://kiali.io/documentation/latest/configuration/authentication/).

The `anonymous` option used above provides free unauthenticated access to the dashboard.

<h3 id="demo-application"><b>Demo application</b></h3>

You’ve deployed Istio, have a running service mesh inside your cluster, and you also installed the Kiali dashboard to observe the traffic.

Let’s now deploy a simple demo application.

You can use the following [hello-world web app](https://github.com/paulbouwer/hello-kubernetes) that will display a simple web page for testing.

Apply the following deployment and service manifests:

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
spec:
  selector:
    matchLabels:
      name: hello-kubernetes
  template:
    metadata:
      labels:
        name: hello-kubernetes
    spec:
      containers:
      - name: app
        image: paulbouwer/hello-kubernetes:1.10
        ports:
          - containerPort: 8080
        env:
        - name: KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: KUBERNETES_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: KUBERNETES_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
---
apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    name: hello-kubernetes
```

Verify that the pod is running and the service is deployed:

```
$ kubectl get pod,svc

NAME                                     READY   STATUS        RESTARTS  	 AGE
pod/hello-kubernetes-78c896db9c-hrcc8  	 2/2 	 Running       0             46s

NAME                   		TYPE        CLUSTER-IP       EXTERNAL-IP   	PORT(S)  	AGE
service/hello-kubernetes  	ClusterIP   10.0.12.41       <none>       	80/TCP	    47s
```

Now, for testing, you can use port-forward to access the application. However, a more permanent solution would be to use a load balancer or an ingress.

Istio has its own ingress controller that you can utilize and test the application.

The following ingress manifest will expose the application on the `/` path:

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: istio
  name: ingress-hello-kubernetes
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello-kubernetes
            port:
              number: 80
```

**Note:** Notice the ingress class annotation; you specify that the Istio ingress controller will pick up this object.

You can get the IP address using:

```
$ kubectl -n istio-system get svc -l release=istio

NAME               		TYPE       		CLUSTER-IP		EXTERNAL-IP    
istio-egressgateway		ClusterIP  		10.0.12.240   	<none>     	                                                                        
istio-ingressgateway   	LoadBalancer    10.0.13.159  	34.140.202.188   
istiod                  ClusterIP  		10.0.8.208		<none>     	
[other output truncated]
```

Visiting the external IP of the ingress gateway will open up the web application.

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61668ab0effdf12585af95cc_image1.png)

To see some activity in the Kiali dashboard, you first need to generate some traffic.

The simplest way is to use curl and a while loop:

From another terminal run:

```
$ while true; do curl 34.140.202.188 ; sleep 1; done;
```

And check the Kiali dashboard:

![](https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/61668b16adf50676c468e783_image3.png)

Success!!

You can now see that Kiali displays the traffic, and it reaches the web application without any issues.

<h3 id="recap"><b>Recap</b></h3>

- You learned what is Istio and how it works
- Got your hands dirty by installing and configuring Istio in a cluster
- In addition to that, you installed Kiali to visualize the traffic in the mesh
- You deployed a demo application and connected it using Istio’s ingress
‍

_[Squadcast](https://www.squadcast.com/) is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil._

[![](https://uploads-ssl.webflow.com/5c51758c58939b30a6fd3d73/60d2ec8e2d9d85d17141958f_footer_banner-2000x761.png)](https://app.squadcast.com/register/)