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.
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
Run the following command to see the Pods running.
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.
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 -
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.
Delete the Nginx Deployment so you can deploy a fresh one in the next section.
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.
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
.
kubectl get namespace -L istio-injection
#OUTPUT
NAME STATUS AGE ISTIO-INJECTION
default Active 42h enabled
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
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
Delete the Nginx Deployment so you can deploy a fresh one in the next section.
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:
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
.
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.