Implementing An Istio Service Mesh Sidecar In Production

Michael Levan - Dec 21 '22 - - Dev Community

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. 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

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.



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


Enter fullscreen mode Exit fullscreen mode

Run the following command to see the Pods running.



kubectl get pods


Enter fullscreen mode Exit fullscreen mode

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

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:



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


Enter fullscreen mode Exit fullscreen mode

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

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



kubectl delete deployment nginx-deployment


Enter fullscreen mode Exit fullscreen mode

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.



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


Enter fullscreen mode Exit fullscreen mode

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



kubectl get namespace -L istio-injection

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


Enter fullscreen mode Exit fullscreen mode

Next, deploy the Nginx Deployment.



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


Enter fullscreen mode Exit fullscreen mode

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



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


Enter fullscreen mode Exit fullscreen mode

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



kubectl delete deployment nginx-deployment


Enter fullscreen mode Exit fullscreen mode

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:



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


Enter fullscreen mode Exit fullscreen mode

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



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


Enter fullscreen mode Exit fullscreen mode

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.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .