Implementing An Istio Service Mesh Sidecar In Production
Tags: kubernetes, devops, docker, cloud
Published: 2022-12-21 12:49:44

Once a Service Mesh is installed, how do you actually get it to work?

It can be running in your Kubernetes cluster, but that doesn’t mean Pods and Services are utilizing the Service Mesh.

Before the Pods and Services can start utilizing it, you have to implement the Service Mesh in the form of a sidecar (a container running beside your main application container in a Pod).

In this blog post, you’re going to learn how to “turn on” a Service Mesh once it’s installed with sidecars.

## What Is A Service Mesh?

This blog post isn’t necessarily written to explain what a Service Mesh is, but instead, to explain how to implement it. If you’d like to learn more in-depth about Service Mesh, check out the blog post found [here](https://dev.to/thenjdevopsguy/kubernetes-ingress-vs-service-mesh-2ee2). However, let’s do a brief overview.

When you deploy Pods and Services, there’s a lot of network traffic happening. Pods are talking to each other. Services are talking to Pods. For example, pod-to-pod communication, which happens often as there’s usually one part of an application per Pod (frontend, backend, middleware, etc.), and you could have many Pods.

There’s a lot of ingress and egress happening between containerized apps.

The problem is, all of this traffic is unencrypted out of the box. You need a third party, whether it’s a Service Mesh or a security-centric Container Network Interface (CNI).

Service Meshes help solve the unencrypted and insecure traffic between Pods and Services, along with some troubleshooting for network latency and observability (tracing and alerting).

## What’s A Sidecar?

When you deploy a Service Mesh, it’s running as Kubernetes resources itself.

For example, see the screenshot below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpzssk101t6lb4w88ixf.png)

The Istio configuration has several Kubernetes resources running that exist in the `istio-system` Namespace which include:

- Pods
- Services
- Deployments

Although Istio is installed and running as expected, that doesn’t mean Kubernetes Pods or Services will utilize Istio out of the box. To confirm that Istio isn’t “on” by default when deployed, run the following Kubernetes Manifest which creates a Deployment that runs Nginx.

```jsx
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginxdeployment
  replicas: 2
  template:
    metadata:
      labels:
        app: nginxdeployment
    spec:
      containers:
      - name: nginxdeployment
        image: nginx:latest
        ports:
        - containerPort: 80
EOF
```

Run the following command to see the Pods running.

```jsx
kubectl get pods
```

Notice how there’s only `1/1`. If Istio was installed as a sidecar, you would see `2/2` as it’s running in the same Pod as a second container.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykjk9kmwoewldcunh9un.png)

Now that we’ve tested to confirm that Istio isn’t installed by default, let’s learn a few different ways to install the Istio sidecar for Pods.

## Manual Sidecar Injection

First, there’s the manual sidecar injection. What this does is manually implement the annotation to install the Istio sidecar for a Kubernetes Deployment.

**Please note** that this isn’t a good “production method” as you don’t want to have to do this for every single Kubernetes Manifest you run, but it is a good way to see how sidecars work for the first time or if you have a one-off Kubernetes Deployment that was perhaps missed with the automated methods that you’ll see coming up.

From the previous section, save the Nginx Manifest as `nginx.yaml`.

After it’s saved, run the following command:

```jsx
istioctl kube-inject -f nginx.yaml | kubectl apply -f -
```

Run `kubectl get pods` again and you’ll now see that `2/2` is available. One of the containers is Nginx and the other container is the Istio sidecar.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lzkeahfld42jz60e99la.png)

Delete the Nginx Deployment so you can deploy a fresh one in the next section.

```jsx
kubectl delete deployment nginx-deployment
```

## Deploy Sidecars Automatically To A Namespace

After understanding the manual method, let’s look at two automated methods. The first is via Namespace labeling.

With a Kubernetes Namespace, you can label it based on what you want “turned on” as the default for every resource running in the Namespace. One of the defaults you can utilize is Istio.

First, label the `default` Namespace with the Istio sidecar injection.

```jsx
kubectl label namespace default istio-injection=enabled --overwrite
```

To confirm that the label was deployed, run the following command to check the labels. Notice how there’s a label called `ISTIO-INJECTION`.

```jsx
kubectl get namespace -L istio-injection

#OUTPUT
NAME                STATUS   AGE   ISTIO-INJECTION
default             Active   42h   enabled
```

Next, deploy the Nginx Deployment.

```jsx
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginxdeployment
  replicas: 2
  template:
    metadata:
      labels:
        app: nginxdeployment
    spec:
      containers:
      - name: nginxdeployment
        image: nginx:latest
        ports:
        - containerPort: 80
EOF
```

Run `kubectl get pods` and you’ll now see `2/2`.

```jsx
kubectl get pods                                
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-588c8d7b4b-99nqd   2/2     Running   0          68s
nginx-deployment-588c8d7b4b-g8x6f   2/2     Running   0          68s
```

Delete the Nginx Deployment so you can deploy a fresh one in the next section.

```jsx
kubectl delete deployment nginx-deployment
```

## Annotation Automated Sidecar Deployment

The last automated method for installing the Istio Sidecar for this blog post is by using Labels.

Labels have a few different purposes in Kubernetes, but for this purpose from an Istio Sidecar perspective, it’s all about metadata. You can use Labels to attach the Istio Sidecar to certain Kubernetes Resources.

For example, in the previous section, the Istio Sidecar deployed to the entire Namespace, which means every Pod in that resource would’ve had Istio injected. However, maybe you don’t want the Istio Sidecar deployed to the entire Namespace, but instead, only deployed to particular Kubernetes Resources in that Namespace.

For Namespace Labelss, you can use the `istio-inject` key and set `enabled` or `disabled` for the value. 

For Pod Labels, you can use the `[sidecar.istio.io/inject](http://sidecar.istio.io/inject)` key and set it as `true` or `false`.

Below, you’ll see the same Kubernetes Manifest as you’ve used previously, except there’s one change - the Label. Notice how under the `labels` map the Istio Sidecar injector now exists.

Run the following Kubernetes Manifest: 

```jsx
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginxdeployment
  replicas: 2
  template:
    metadata:
      labels:
        app: nginxdeployment
        sidecar.istio.io/inject: "true"
    spec:
      containers:
      - name: nginxdeployment
        image: nginx:latest
        ports:
        - containerPort: 80
EOF
```

Run `kubectl get pods` and you’ll now see `2/2`.

```jsx
kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-75ccf754b7-s7mb6   2/2     Running   0          7m48s
nginx-deployment-75ccf754b7-xg5rf   2/2     Running   0          7m48s
```

Congrats! You have successfully injected the Istio Sidecar utilizing three different methods. Remember, you always want to use the two automated methods when possible in production. The last thing you want is to manually inject Istio for every single Kubernetes Deployment.