Container technology helped popularize the concept as it made it possible to run and scale different components of the applications in self-contained units with independent runtimes. While a microservices architecture enables faster delivery by reducing the scope of change to smaller parts, improving system resilience, simplifying testing, and scaling parts of the application independently, implementing it has its challenges.
Microservices are a management and security nightmare. Instead of having one monolithic application, as you now have multiple moving parts, each catering to specific functionality. An extensive app can use hundreds of microservices interacting with each other, and things can get overwhelming pretty fast.
The main questions your security and operations teams may ask you are:
- How do we ensure that communication between the microservices is secured? Instead of securing one monolithic application, we need to secure hundreds of smaller services.
- In case of an issue, how do we isolate the microservice to fix the problem?
- How do we consolidate the application logs as now they are spread in multiple places?
- How do we check the health of the services? With more components making the application, the task of application monitoring has become more complex.
While Kubernetes addresses some of the management issues, it is supposed to be a container orchestration platform, and it is very good at that. It does not solve the problems of microservices architecture, and it has a different purpose. Service management isn’t Kubernetes’ expertise and, therefore, it does not answer all of it by default.
Communication between Kubernetes containers by default is insecure, and there is no easy way to enforce TLS between pods as you would end up maintaining hundreds of TLS certificates all by yourself. Pods communicating between each other do not apply identity and access management between them.
Though there are tools such as Kubernetes Network Policy you can implement to run a firewall between pods, they are a layer 3 solution rather than a layer 7 solution, which is what most modern firewalls are.
That means that, while you can know the source of traffic, you cannot peek into the data packets to understand what they contain. That does not allow you to make vital metadata-driven decisions such as routing on a new version of a pod, based on an HTTP header. There are Kubernetes Ingress objects which do provide a reverse proxy based on layer 7, but they don’t offer anything more.
Kubernetes does offer different ways of deploying your Pods and conducting some form of A/B testing and canary deployments. It is more through implementing replicas of containers that this is achieved. For example, if I want to deploy a new version of a microservice and pass 10% of traffic through it, I have to scale my containers to at least ten, nine being the old version and one is the new version.
Kubernetes cannot split the traffic intelligently and instead just load-balances between Pods in a round-robin fashion. Every Kubernetes container within a Pod has separate logging, and you have to implement a custom solution over Kubernetes to capture and consolidate them.
Although the Kubernetes dashboard offers features such as monitoring Pods and checking their health, it does not provide how the components interact with each other, how much traffic is flowing through each of the Pods, and what chains of containers make up the application. As you cannot trace traffic flow through Kubernetes Pods, you cannot tell on what part of the chain the failure occurred for the request.
You can address all these problems by using a service mesh technology such as Istio.
So, what is Istio? Istio is a service mesh technology that helps connect, secure, controleg, and observe services.
When you run a microservices application, every individual microservice runs independently in containers. As a result, they have many interactions with each other. A service mesh enables you to discover, enable, and control these interactions, often using a side-car proxy. Too many technical terms? Let me declutter things for you one by one.
Let us take a typical example of a Kubernetes application with a front-end and a back-end Pod. Kubernetes offers an inbuilt service discovery between Pods using Kubernetes services and CoreDNS. Therefore, you can route from one Pod to another using the service name. However, you won’t have much control over how these interactions work, and what to do with the runtime traffic.
Istio injects a side-car container within your Pod which acts as a proxy, and your main container communicates with the other container through the proxy. Now, since all requests go via the proxy, you can control the traffic and gather the data to do what you want with them. You can also encrypt communication between Pods and enforce identity and access management using a single control plane.
The Core Functionalities of Istio
Istio has the following core functionalities.
Because of the side-car proxy (also known as the envoy proxy) and Ingress and Egress gateways, Istio manages traffic and creates routing rules that allow you to control traffic and define interactions between services.
You can do cool things like implementing timeouts, retries, circuit breakers, and much more, all by changing configurations in a control plane. That allows you to do smart things such as A/B testing, canary deployments, and staged rollout with traffic splitting based on percentages.
It helps you slowly roll out a release and move gradually from an existing version (blue) to a new version (green) all out of the box with simple controls.
If you need to run an operational test in production and see how your product behaves in live traffic, you can do live traffic mirroring to your test instances. As a result, you can gather live insights and identify potential production issues even before you go live!
You can also have an app running multiple language-specific versions of microservices and use geolocation or the user’s profile to route requests to the correct version, and much more!
Istio enables you to secure your microservices through an envoy proxy by establishing identity access management between Pods through mutual TLS.
They help you defend against man-in-the-middle attacks as they offer traffic encryption between Pods out of the box. That is, there can be a mutual authentication between a front end and a back end, and only the front end can connect to the back end. The back end only trusts the front end and vice versa, so if one of the Pods gets compromised, no one can do anything with the rest of your application.
Istio also provides you with features to limit access through fine-grained policies and determines what is going on in your cluster using auditing tools that Kubernetes lacks at the moment.
Because of the envoy sidecar, Istio is aware of the traffic through the Pods and therefore gathers telemetry details from the services. That helps in gaining insights about service behavior, and you can learn about future possibilities that you can use to optimize your applications.
It also consolidates application logs and can enable traffic tracing through multiple microservices. That assists you in identifying issues faster and allows you to isolate the faulty service and fix it.
DevSecOps for your team
The best thing Istio offers is the fact that it does not burden developers with worrying about the security and management details of their implementation.
As Istio is Kubernetes-aware, they can still develop their applications like a standard Kubernetes deployment, and Istio automatically injects sidecar containers into the Pods.
Once Istio inserts the sidecar containers, the operations and security teams can enforce policies to the traffic and help secure and operate the application – a win-win situation for everyone!
Istio empowers the security and operations teams to effectively monitor microservices applications without killing the productivity of your development team.
It also enables teams within the organization to retain their niche and look at their areas of expertise.