IBM Developer

Tutorial

Generate microservices dependency graph for your applications

Learn how to generate and visualize a service dependency graph using Istio, Prometheus, Jaeger, and Kiali

By Aishwariya Chakraborty

Microservices-based applications consist of numerous interconnected components that interact through APIs to deliver diverse functionalities. These components include standalone services, databases, load balancers, caching systems, and more. This architecture enables users to develop and scale each part of an application independently, providing flexibility and ease of reuse.

Drawbacks of microservices-based applications

Despite their advantages, microservices-based applications suffer from two major drawbacks:

  • Increased dependency complexity: Microservices depend on one another to deliver various functionalities. As the number of microservices increases, more dependencies are created, increasing the complexity of the architecture.
  • Challenging debugging: The distributed nature of microservices makes it difficult to locate and debug failures. Each microservice has its own observability data, such as metrics, events, logs, and traces, which need to be examined to pinpoint the cause of failures.

Addressing drawbacks with Service Dependency Graphs

One basic approach to address these drawbacks is to outline the dependencies between various microservices by analyzing their interactions. This is typically done with the help of a Service Dependency Graph (SDG), where nodes represent different microservices and directed edges capture the dependencies between them. These dependencies can be derived from static artifacts such as source code, documentation, and configuration files, or dynamically from logs, traces, etc., generated during runtime. Thus, an SDG provides a way for developers to visually analyze the structure of the microservices constituting an application and gain insights into possible sources of problems.

Steps to generate and visualize the SDG

This tutorial outlines the steps to automatically generate and visualize the SDG of a microservices-based application using Istio with Prometheus, Jaegar, and Kiali. We consider the Quote of the Day (QotD) application as an example, shown in the following figure, deployed over a local Kind cluster. We also discuss a way to programmatically extract information from the SDG and make necessary edits to the graph image as required.

alt

Installing Istio Service Mesh

Assuming we have an existing Kind cluster (with Kubernetes version among 1.25 - 1.29, required for Istio v1.20), we first install Istio Service Mesh. The simplest method is using istioctl. To do this, we first need to download Istio and add istioctl to the PATH variable by following the steps mentioned below:

  1. Download and configure Istio:

     curl -L https://istio.io/downloadIstio | sh -
     cd istio-1.20.2
     export PATH=$(pwd)/bin:$PATH
    
  2. Verify Istio configuration:

     istioctl x precheck
    

    A correct configuration will display:

     ✔ No issues found when checking the cluster. Istio is safe to install or upgrade!
     To get started, check out https://istio.io/latest/docs/setup/getting-started/
    

    Next, we use istioctl to install Istio. There are multiple built-in configuration profiles such as default, demo, minimal, and preview, which allow users to customize the Istio control plane and the sidecars of the Istio data plane. In this blog, we use the demo profile, which includes istio-ingressgateway, istio-egressgateway, and istiod (dataplane).

  3. Install Istio:

     istioctl install --set profile=demo -y
    
  4. Verify Istio deployment:

     kubectl get all -n istio-system
    

Deploying telemetry Add-ons

The next step is to deploy the provided telemetry add-ons, including Prometheus, Jaeger, and Kiali, for enabling SDG visualization, and check their deployment status:

kubectl apply -f samples/addons

Once the rollout is complete, we can view the Kiali dashboard by executing the following:

istioctl dashboard kiali

Deploying the QotD application

The QotD application is a demonstrative application with eight microservices and one database. It also includes a load generator component capable of continuously generating random requests to the server. Although the service graph of this application is provided in the project, it lacks information regarding the level of these interactions, typically represented by the weights of the edges. In this tutorial, we explore a method to get this information.

As mentioned in the project documentation, there are multiple ways to deploy QotD, with the simplest approach being the use of the Helm package manager, which is discussed in this tutorial.

  1. Before installing the application, we must first create the required namespaces for the application and the load generator module as follows.

         kubectl create ns qotd
         kubectl create ns qotd-load
    
  2. Next, we need to enable Istio sidecar injection in these namespaces so that an Istio sidecar is automatically inserted with each of the microservice pods. These sidecars are responsible for collecting information about the interactions among the microservices.

         kubectl label namespace qotd istio-injection=enabled
         kubectl label namespace qotd-load istio-injection=enabled
    
  3. Finally, we follow the steps below to deploy QotD on our Kind cluster.

     helm repo add qotd https://gitlab.com/api/v4/projects/26143345/packages/helm/stable
     helm repo update
     helm install qotd qotd/qotd --set useNodePort=true -n qotd
    
  4. After deployment, we can verify that each of the microservice pods has two containers, one of which is the Istio sidecar.

     kubectl get all -n qotd
    
  5. To view the web portals of the application and the load generator, we can use port forwarding as mentioned below. Note that the services qotd-web and qotd-usecase are exposed on ports 3000 and 3012, respectively, by default. In the following commands, localhost_port_1 and localhost_port_2 should be replaced with the port numbers on which we want to view the two dashboards.

     kubectl port-forward service/qotd-web <localhost_port_1>:3000 -n qotd
     kubectl port-forward service/qotd-usecase <localhost_port_2>:3012 -n qotd-load
    

Viewing the SDG

After the pods in the qotd and qotd-load namespaces are running, we can view the SDG in the Kiali dashboard by selecting the Graph option in the left-hand side panel and choosing the qotd and qotd-load namespaces from the Namespace dropdown list.

alt

Customizing the SDG

Kiali allows customization of the SDG in various ways:

  • Type of Graph

    alt

  • Traffic type

    alt

  • Display items

    alt

Additionally, the layout of the graph can be altered using the symbols in the menu located in the bottom left corner of the portal. By selecting the options as shown above, we get an SDG in the following format:

alt

Notably, other parameters that can be selected as edge weights include throughput and delay. The traffic animation option provides a visual representation of the flow of traffic between the microservices. For more details on these options, refer to the documentation.

Graph extraction and modification

Kiali also allows users to export the graph in JSON format, which can be parsed and read into a graph data structure for further processing. For example, using the JSON and networkx packages in Python, users can explore the graph with various common graph algorithms and analyze its properties. This functionality is particularly useful for understanding the architecture of the distributed application and identifying areas of concern.

To export the graph in JSON format, click the ? option in the menubar at the top of the portal and select the View Debug Info option from the dropdown list.

alt

The Debug information dialog box displays the configuration of the Kiali service under the Kiali Config tab and the graph JSON under the Additional State tab. This JSON can be downloaded using the Download option at the bottom of the dialog box.

alt alt

Conclusion

Following the steps outlined above, we can easily generate the SDG of any application built using the microservices architecture. This approach can also help to analyze the structure of legacy applications that have been converted from monoliths to microservices using tools such as IBM Mono2Micro. The SDG can then be used for downstream tasks such as detecting and mitigating possible bottlenecks and identifying deadlock situations.

References