Istio is the perfect complement to Kubernetes. An elegant and complete networking solution, that also provides log management and monitoring on several platforms (Prometheus, Grafana, Jaeger, Servicegraph, etc.), which is directly integrated into its “control plane”.
In this article, more than deconstruct; explaining separately each component Istio consists of, we will see what Istio is, and how it can simplify the management of a cluster, as it grows. We will also see the approaches that an administrator should change, and the difference between the data management of a cluster; with, and without Istio.
Moving from a monolithic application to micro-services, not all are advantages. A monolithic application can be divided into dozens of micro-services. As a cluster grows, it is inevitable to have several tens, and even hundreds of services running; with different versions, in different environments, etc. In such a circumstances, it is not easy to visualize the cluster, and, with time, one can get prone to mistakes.
What is Istio, and how can it help with cluster management
Istio is a service mesh, which provides traffic management, implementation of compliance policies and collection of metrics. A service mesh is a dedicated infrastructure layer to manage service-to-service communication.
In Istio, this is achieved by configuring “Envoy” based proxies, which is added to the pods, as “sidecar” container, and imposes the natural flow of traffic to the appropriate backend, while disabling other services that communicate with it. In addition, services do not communicate directly, but through their sidecar containers (“Envoy”). The component in charge of this process is the “Pilot”.
Some readers may have realized that with this behavior, Istio satisfies some requirements that would be achieved with NetworkPolicies
In the figure above it is illustrated how services A and B do not communicate directly, but they do through their associated Envoy sidecar containers. So if service A wanted to send a packet to service B, it would pass it to its Envoy container, which would send it to the Envoy container of service B, which in turn would pass it to service B.
If service B had several replicas, Pilot would be responsible for the distribution of the load in a homogeneous way, as well as it could be configured to send part of the requests, arbitrary or based on some criteria, like headers, to a service B’.
The collection and visualization of the metrics is an extra feature to be grateful for. The truth is that it is a pretty clever from Istio team. Once the packet is set to be routed, it does not cost anything to multiplex it to another block and get the most out of the traffic. The block that is responsible for this task is the Mixer.
Mixer applies compliance policies along the mesh (check if service A is configured to talk to service B), and collects metrics from Envoy sidecar containers and other services (figure below). It also provides several additional features in Istio. Due to its general-purpose plugin model, it is possible to expand the infra-structural backends with which Mixer can interact relatively easily. It involves programming an adapter though.
Istio comes with several built-in Mixer adapters(drivers); that allows with minimum configuration to achieve a particular purpose, such as having the logs and metrics in the tool of our choice
For monitoring in Prometheus, we would pass the metrics to the Prometheus adapter, and the Mixer would take care of the rest.
The good thing about Istio is that it is implemented as an extension of kubernetes, which makes the objects to be integrated into the api-server. This causes the admin to have to learn some new objects of kubernetes, and its purpose, instead of deploying a decoupled application, and configure it.
This is an advantage provided by Kubernetes, not Istio directly.
The new objects to be highlighted, for traffic management, are Gateway, VirtualSevice and DestinationRule. These objects combined, and the Istio plane control, allow to replace the default ingress controller, or integrate one, if there is no any. In GKE, this would imply a more granular and flexible traffic control, and lower cost. Next we are going to see these objects, and their purpose.
- Gateway: The Gateway object describes how traffic should enter the cluster. This object would typically define the port, the protocol, the host, information about the certificate and the TLS key, etc. An application would have to satisfy the requirements required to enter the cluster.
- VirtualService: A VirtualService is linked to a Gateway. In this object, routing rules are defined; that apply to all applications that have exceeded the requirements of the Gateway, to which it is linked. A typical configuration would be to distribute the traffic between several backends, according to the path.
- DestinationRule: The DestinationRule defines rules, which apply to a request, that has already been routed to a particular service. It may be the case that we have several versions of the same application. You could define a subset of the application, and depending on some parameters, send the traffic to one version or another. These checks would be done in the VirtualService.
This is a slightly different approach to using an Ingress type object, which would route the packet to a service, which would end up in a pod. And, even if Istio is able to manage an Ingress object, it may not be a very good idea, because of the flexibility of the alternative described above. In other words, Istio manages the traffic entering the cluster in its own way, which turns out to be more appropriate, to the conventional Ingress object.
Also, although in the same way, with these objects Istio achieves cluster behaviour similar to one with NetworkPolicies.
In Istio, unauthorized communication is blocked for both; ingress and egress. The objects described above cover the ingress rules. For egress, there is one object to point out; ServiceEntry.
- ServiceEntry: The ServiceEntry object allows you to add external services to the cluster, to the mesh. That is, if we wanted to access “google.com”, for example, from a pod inside the mesh, we wouldn’t be able to unless we added a ServiceEntry allowing access to “google.com”.
For log management and monitoring, there are several objects; that are grouped into three types; instances, handlers and rules. Next we will see what they are. Recall, from Mixer, that Istio has several adapters, very popular tools, integrated by default.
- Instances: An instance defines the attributes that must be passed to an adapter. Typically it could be a metric.
- Handler: A handler is responsible for delivering the attribute to the adapter. If we say that Istio has several adapters integrated by default, we are saying that it has several types of pre-defined handlers.
- Rule: A rule binds an Instance to a handler.
For example, if we wanted to monitor an application in Prometheus, we would create a metric type object, which would be the instance, in which we would define the metrics we want to monitor. We would also create a prometheus type object, which would be the handler, where we would define how we want to process and format the metrics. Finally, a rule type object would link the instance with the handler, so that Mixer knows how to act.
Istio, by default, collects the metrics from the control plane. Which makes easier to identify certain problems. You would have to configure only the metrics of your application. Below, an example of Grafana with the service mesh dashboard.
Stay tuned for part 2!