5 minute read

How can we deploy microservices within Service Mesh easily and automatically? How to control and istiofy them? And what are the main components involved?

Let’s Mesh in!!

This is the second blog post of the Service Mesh in OpenShift series. Check the earlier post:

Overview

In this blog post, we will deploy four microservices that will help us show the capabilities of Istio.

NOTE: this blog post is supported by the istio-files repository located in my personal Github

0. Prerequisites

  • OpenShift 4.x cluster (tested in a 4.3+ cluster)
  • OpenShift Service Mesh Operators installed (v1.1.1 in these blog posts)
  • Service Mesh Control Plane deployed
  • Free time to have fun with Service Mesh!

Export the useful variables that will be used to customize the Namespace where our microservices will be installed:

export OCP_NS=istio-tutorial

1. Deploy the microservices of our application

The microservices used in this tutorial are composed of customer / partner, preference and recommendation. The workflow between them is as follows:

( customer | partner ) ⇒ preference ⇒ recommendation

So as we can see, if we request the customer/partner microservice route, internally these apps will call the services of preference, and then finally recommendation.

  • Deploy the customer v1 microservice using oc new-app, that will deploy a service, a route, a deploymentconfig and the pods of customer:
oc new-app -l app=customer,version=v1 --name=customer --docker-image=quay.io/rcarrata/customer:quarkus -e VERSION=v1 -e  JAVA_OPTIONS='-Xms512m -Xmx512m -Djava.net.preferIPv4Stack=true' -n $OCP_NS

oc expose svc customer -n $OCP_NS

Pay attention to the labels of these microservices: app=customer and version=v1, which are very important for our purposes.

  • Deploy the partner v1 app:
oc new-app -l app=partner,version=v1 --name=partner --docker-image=quay.io/rcarrata/partner:sb -e JAVA_OPTIONS='-Xms512m -Xmx512m -Djava.net.preferIPv4Stack=true' -n $OCP_NS

oc expose svc partner -n $OCP_NS

As you can see, both partner and customer will expose an OpenShift route. Nothing weird so far, right?

  • Deploy the preference v1 app:
oc new-app -l app=preference,version=v1 --name=preference --docker-image=quay.io/rcarrata/preference:quarkus -e JAVA_OPTIONS='-Xms512m -Xmx512m -Djava.net.preferIPv4Stack=true'  -n $OCP_NS

This microservice app does not need any route because only customer or partner need to be reached externally. When the request reaches these two microservices, they internally use the services of OpenShift/Kubernetes to communicate with the preference and recommendation microservices.

  • Deploy the recommendation v1 app:
oc new-app -l app=recommendation,version=v1 --name=recommendation --docker-image=quay.io/dsanchor/recommendation:vertx -e JAVA_OPTIONS='-Xms512m -Xmx512m -Djava.net.preferIPv4Stack=true' -e VERSION=v1 -n $OCP_NS

2. Test our microservices (outside of the Mesh)

Let’s test our microservices routes:

$ oc get route | egrep -i 'customer|partner'
customer   customer-istio-tutorial.apps.ocp4.rglab.com          customer   8080-tcp None
partner    partner-istio-tutorial.apps.ocp4.rglab.com           partner    8080-tcp None

As we can see the customer and partner have the same “behaviour”:

$ curl partner-meshtutorial.apps.ocp4.rglab.com
partner => preference => recommendation v1 from 'recommendation-1-9d977': 7
$ curl customer-meshtutorial.apps.ocp4.rglab.com
customer v1 => preference => recommendation v1 from 'recommendation-1-9d977': 8

3. Including our microservices in our Service Mesh

Until now, this deployment of these apps is a regular deployment with all of the “traditional” components, including Services, Routes, and DeploymentConfigs among others.

But to enable the Service Mesh capabilities, we need to include these microservices in our Service Mesh. How can we accomplish that? With sidecar autoinjection.

But first, two important things that need to be discussed: sidecar containers and the Istio data plane.

Istio data plane is built as a sidecar container, which is deployed together with our applications running in the same pod (yes, same pod).

So in overview, in order to take advantage of all of Istio’s features, pods in the mesh must be running an Istio sidecar proxy.

3.1 Differences between Istio upstream and RH Service Mesh / Maistra

Enabling automatic injection for your deployments differs between the upstream Istio releases and the Maistra releases. The upstream sidecar injector injects all deployments within labeled projects whereas the RH Service Mesh / Maistra version relies on presence of the sidecar.istio.io/inject annotation and the project being listed in the ServiceMeshMemberRoll.

More information could be found in:

3.2 Enabling the sidecar autoinjector

To enable the sidecar autoinjector in our Pod, we will have to annotate them with the following annotation:

sidecar.istio.io/inject: true

But usually, we don’t annotate the Pods directly, instead we will annotate the controller such as DeploymentConfigs or Deployments (among others).

The annotation needs to go under “spec.template.metadata.annotations”. Remember that you need to be strict about this — it is not valid to put it at the metadata.annotations level, where annotations usually go.

As we discussed in the section before, one of the differences with Istio upstream is that here we annotate the deploymentconfigs, and not annotate the .

To enable the autoinjection of our DeploymentConfigs, run the following patch:

oc patch dc/customer -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"true"}}}}}' -n $OCP_NS

oc patch dc/preference -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"true"}}}}}' -n $OCP_NS

oc patch dc/recommendation -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"true"}}}}}' -n $OCP_NS

oc patch dc/partner -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"true"}}}}}' -n $OCP_NS

Then a rolling process will be triggered, and new pods will be created. You will know they are ready when you see two containers per pod (2/2):

$ oc get pod | grep -i Running
NAME                      READY   STATUS      RESTARTS   AGE
customer-2-4gkzf          2/2     Running     0          42s
partner-2-4q8zl           2/2     Running     0          39s
preference-2-nxh2v        2/2     Running     0          39s
recommendation-2-cj25h    2/2     Running     0          39s

As we can see we have two containers running in the same pod: istio-proxy and our container app.

3.3 Controlling the namespaces allowed to be in our Mesh

Last but not least, an interesting topic is how to control which namespaces are allowed to include apps in the mesh. This is controlled by the ServiceMeshMemberRoll.

The ServiceMeshMemberRoll resource configures which projects belong to a control plane. Only projects listed in the ServiceMeshMemberRoll will be affected by the control plane. Any number of projects can be added, but a project may not exist in more than one control plane.

This resource must be created in the same project as the ServiceMeshControlPlane resource.

$ oc get ServiceMeshMemberRoll -n istio-system -o yaml | grep spec -A3
 spec:
   members:
   - bookinfo
   - istio-tutorial

For more information refer to the Configuring Members in Maistra documentation.

And that’s it! Hope that helps!

Check out the part three of this blog series in Including microservices in ServiceMesh

NOTE: Opinions expressed in this blog are my own and do not necessarily reflect that of the company I work for.

Happy ServiceMeshing!