Kubernetes

Service Mesh comparison – Istio vs LinkerD

What is a service mesh?

A service mesh is in charge of managing the network traffic between the services. It does it in a more automated and scalable way compared to otherwise what it would take a lot of manual work. (and we know that manual work is not good 🙂 )

In other words, the service mesh lays in top of Kubernetes, takes over your services networking and makes the communications safe and reliable. It allows to connect, secure and monitor your services.

You can focus on writing your microservices and leverage the observability, network, and security policies to the service mesh.

Key capabilities of a service mesh

We can split the key capabilities in three:

  • Traffic Management
    • mTLS
    • Fault Injection
    • Circuit Breaking
    • Deployment Strategies
  • Metrics/Observability
    • Out-of-the-box monitoring and tracing tools
  • Security/Policies
    • Enforce policies and isolation

A service mesh enables “intelligent route control” capabilities, along with end-to-end encryption in the communications between the services. In addition, it also enables fault injection and advanced deployment strategies like blue/green, canaries, rolling upgrades, and more.

A service mesh becomes the “dashboard of your microservices“, a place where you can view and control what’s going on inside your cluster.

Service mesh comparison

When it comes to service mesh for Kubernetes, there are two big players, Istio and LinkerD. Both have amazing features and work in a very similar way so it is often a complicated choice.

Istio

  • Istio is a Kubernetes native service mesh, but it supports other orchestration tools like Consul and even VMs.
  • It was created by Lyft, but Google and IBM are now supporting it. Today Anthos comes with “Istio” service mesh capabilities.
  • It relies on a control plane and sidecars for working
  • We can say it is the most popular Kubernetes Service Mesh
  • It is very customizable
  • It is complex

LinkerD

  • Mirrors Istio architecture closely. (sidecars, control plane)
  • It is part of the Cloud Native Foundation (CNCF)
  • LinkerD focuses on simplicity instead of Flexibility
  • It is a Kubernetes-only solution
  • We can say it is the second most used Kubernetes service mesh

Comparison Table

Here you can find a summary of a comparison between the features:

ISTIOLINKERD
Mesh Features
Encrypted trafficYes. Auto mTLSYes, but not for TCP. (mongo connection)
Inter microservices traffic managementYes. PoliciesLimited
Microservices metrics for automatic scalabilityYes. PrometheusYes. Prometheus
Real-time mesh status observabilityYes. Kiali. (more graphical)Yes. (own dashboard, simpler)
Microservices Rate LimitingYesNo
Microservices Testing Features (fail injection, delays, % balancer)YesLimited
Microservices Circuit breakingYesNo
Microservices Release mechanisms (canary, green/blue, etc.)YesYes
Monitoring integration and metrics standards (opentelemetry)Yes. Grafana, Jaeger (tracing)Yes
Access Logs GenerationYesNo out-of-the-box (possible with plugins)
Does it work for Inter-cluster communications? (multi-cluster)YesNo
Mesh Generic stuff
ComplexityHighLow
Easy of UseComplexMedium
Companies behind itGoogle, Lyft, IBMBuoyant
Market acceptance/maturity. Community sizeLargeMedium
Support ModelCommunity and Google on AnthosCommunity. Buoyant
License/CostApache 2.0Apache 2.0
ProsMany Features. Can be extended.Easy to Use
ConsComplexDeeply Integrated with kubernetes. Cannot be expanded.

Comparison Conclusion

In conclusion, Istio is very flexible, but it is also very complex, therefore the learning curve is really big, yet it allows you to do more. LinkerD on the other hand focuses on simplicity, so it is easy to use but less customizable.

Resource management strategy for docker containers on Kubernetes (nodejs + express)

It seems simple, but it is not.

How to properly assign resources requirements and limits to a HTTP dockerized microservice running on kubernetes?

Good question, right?

Well, as you can imagine there is not a single answer to it. But there is a strategy you can follow. This is not a “book definition” what I mean with this is that there might be another way of sizing resource requirements, but, so far, I’ve been using this method successfully.

It is a delicate balance between the hardware size on which your containers will run (ie: k8s nodes) and how many requests the container itself can handle.

The idea is to find that delicate balance so our pods can be scheduled on the nodes, without wasting precious resources that can be used for other workloads.

So, how do we do that?

A simple method:

Let’s take a simple microservice as an example: a nodejs express REST API which talks to a MongoDB.
We will be doing: GET /example

Run the container on your local machine or a k8s cluster, measure the idle resource usage:

  • CPU: 1%
  • Memory: 80Mb


Using a load testing app like Apache JMeter, we fire up 100 concurrent requests in 1 second… measure the resource spike using docker stats or similar:

  • CPU: 140%
  • Memory: 145Mb

We exceeded one CPU core, and that is not good, so we reduce the number of parallel requests to 70

  • CPU: 93%
  • Memory: 135Mb

Now, we have something to work with. We can assume that a single instance of our app, can handle up to 70 requests per second.

Setting Kubernetes resources:

According to how resource limits and requests are set in Kubernetes, we can say that it is safe to consider that our resource requests can be:

  • CPU: 0.1
  • Memory: 100Mb

And we can limit the resources to:

  • CPU: 1
  • Memory: 150Mb

That will ensure that we can handle at least, 70 requests per second, per replica.

Disclaimer: as I said before, this is a simple approach, we are not considering several things, for example, node resources, MongoDB capacity…