May 5, 2025

Istio, Kiali + Kubernetes: Service Mesh your Microservices

In this guide, you will learn how to implement a powerful Istio service mesh for your microservices architecture. First, you will install Istio and all its components using Helm. Then, you will deploy a complete microservices-based ecommerce application and inject Envoy sidecars into each service to bring them into the mesh. Next, you will use Kiali to visualize and understand the traffic flow between your services. You will then implement a canary deployment strategy for safely rolling out new versions of your services with controlled traffic splitting. After that, you will configure circuit breaking to automatically detect problematic services and route traffic away from them to prevent cascading failures. Finally, you will set up comprehensive monitoring with Grafana dashboards to track service performance and explore the distributed tracing capabilities with Jaeger to follow request paths across services.

Table of Contents

  1. Installing Istio for Your Microservice Architecture

  2. Deploying Microservices to Your Istio Service Mesh

  3. Monitoring and Observing Your Service Mesh with Kiali

  4. Implementing Canary Deployments with Istio

  5. Implementing Circuit Breaking with Istio

  6. Monitoring Your Istio Service Mesh with Grafana

  7. Distributed Tracing: Current Jaeger Implementation

Prerequisites

To follow along with this tutorial, you'll need:

New to Kubernetes? Check out our Kubernetes Training course: https://www.udemy.com/course/kubernetes-bootcamp-kubernetes-from-zero-to-cloud/?couponCode=FRAMER_3

Want to Learn More?

Want to become cloud-native? Master Kubernetes with our Complete Course https://www.udemy.com/course/kubernetes-bootcamp-kubernetes-from-zero-to-cloud/?couponCode=FRAMER_3

Installing Istio for Your Microservice Architecture

This chapter guides you through setting up Istio, a powerful service mesh that provides traffic management, security, and observability features for your microservices. I'll explain each command and its purpose as we progress through the installation.

1. Creating the Istio Namespace

First, we create a dedicated namespace for Istio components:

This creates an isolated Kubernetes namespace where all Istio control plane components will reside.

2. Adding the Istio Helm Repository

Next, we add the official Istio Helm repository to access installation charts:

This command registers the Istio chart repository with your local Helm installation.

3. Updating Helm Repositories

To ensure we have the latest charts:

This synchronizes your local Helm cache with the latest charts from all configured repositories.

4. Installing Istio Base Components

We begin by installing the Istio base package:

helm install istio-base istio/base -n istio-system --version 1

This installs the Istio Custom Resource Definitions (CRDs) and base components needed for the control plane.

5. Installing Istiod (Control Plane)

Now we install the Istio control plane:

helm install istiod istio/istiod -n istio-system --version 1.25.2 --wait

Istiod is the central component that manages configuration, certificates, and sidecar injection. The --wait flag ensures Helm waits until the deployment is complete.

6. Preparing for Application Deployment

Create a namespace for your ecommerce application and enable automatic sidecar injection:

kubectl create namespace ecommerce
kubectl label namespace ecommerce istio-injection

The istio-injection=enabled label instructs Istio to automatically inject Envoy sidecars into all pods deployed in this namespace.

7. Installing the Ingress Gateway

Deploy the Istio ingress gateway to manage inbound traffic:

helm install istio-ingress istio/gateway -n istio-system --version 1

This creates an entry point for all external traffic into your service mesh.

8. Verifying the Installation

Check that all components are running properly:

kubectl get pods -n istio-system
kubectl get svc -n

These commands display the status of Istio pods and services. You should see the control plane (istiod) and ingress gateway running successfully.

9. Installing Observability Add-ons

Finally, set up monitoring and visualization tools:

mkdir -p istio-addons
curl -L https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/prometheus.yaml -o istio-addons/prometheus.yaml
curl -L https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/grafana.yaml -o istio-addons/grafana.yaml
curl -L https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/kiali.yaml -o istio-addons/kiali.yaml
curl -L https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/jaeger.yaml -o istio-addons/jaeger.yaml

kubectl apply -f istio-addons/prometheus.yaml
kubectl apply -f istio-addons/grafana.yaml
kubectl apply -f istio-addons/kiali.yaml
kubectl apply -f

These commands deploy:

  • Prometheus for metrics collection

  • Grafana for metrics visualization

  • Kiali for service mesh visualization

  • Jaeger for distributed tracing

With these components installed, your Istio service mesh is now ready for deploying microservices with advanced traffic management, security, and observability capabilities.


Deploying Microservices to Your Istio Service Mesh

Now that we have Istio installed, it's time to deploy our microservices-based ecommerce application. This chapter walks through deploying the complete application stack and configuring the service mesh to handle external traffic.

  1. Understanding Our Microservices Architecture

Our ecommerce application consists of several microservices, each responsible for a specific business function:

  • ecommerce-ui: The frontend React application that users interact with

  • product-catalog: Manages product listings and details

  • product-inventory: Tracks product availability

  • profile-management: Handles user profiles and authentication

  • order-management: Processes customer orders

  • shipping-and-handling: Manages shipping logistics

  • contact-support-team: Provides customer support functionality

  1. Deploying the Microservices

To deploy all microservices at once, we can use:

kubectl apply -f

This command deploys all Kubernetes resources defined in YAML files within the microservices directory. Each microservice is deployed with its own:

  1. Deployment: Manages pod creation and scaling

  2. Service: Enables service discovery within the cluster

The frontend ecommerce-ui service is configured to connect to all backend services through environment variables, allowing it to communicate with other components through their service names.

  1. Configuring Istio for Traffic Management

After deploying our microservices, we need to configure Istio to manage traffic properly:

kubectl apply -f

This applies three important Istio resources:

  1. Gateway: Creates an entry point for external traffic to access your application

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: ecommerce-gateway
      namespace: ecommerce
    spec:
      selector:
        istio: ingress
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"

    This Gateway configures the Istio ingress gateway to accept HTTP traffic on port 80 for all hosts.

  2. VirtualService: Defines routing rules for traffic entering through the Gateway

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: ecommerce-gateway-routes
      namespace: ecommerce
    spec:
      hosts:
      - "*"
      gateways:
      - ecommerce-gateway
      http:
      - match:
        - uri:
            prefix: /
        route:
        - destination:
            host: ecommerce-ui
            port:
              number: 4000

    This VirtualService routes all incoming traffic to the ecommerce-ui service.

  3. PeerAuthentication: Secures service-to-service communication

    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: default
      namespace: ecommerce
    spec:
      mtls:
        mode
    
    

    This enables strict mTLS (mutual TLS) for all services in the ecommerce namespace, ensuring all service-to-service communication is encrypted.

  4. Accessing the Application

With everything deployed, you can now access the ecommerce application by navigating to:

Istio's ingress gateway (which we configured in Chapter 1) listens on port 80 and routes traffic to our ecommerce-ui service, which then communicates with all the backend services.

  1. Generating Traffic and Observing the Service Mesh

I encourage you to explore the application by:

  1. Browsing product listings (generates traffic to product-catalog)

  2. Checking product availability (connects to product-inventory)

  3. Creating an account (engages profile-management)

  4. Adding items to cart and checking out (utilizes order-management)

  5. Viewing shipping options (uses shipping-and-handling)

  6. Submitting a support request (interacts with contact-support-team)

While you interact with the application, you can observe the traffic flow through your service mesh using the monitoring tools we installed earlier:

  • Kiali: View service mesh topology, traffic flow, and health

    kubectl port-forward svc/kiali -n istio-system 20001

    Then visit http://localhost:20001 in your browser


  • Grafana: View detailed metrics and create dashboards

    kubectl port-forward svc/grafana -n istio-system 3000

    Then visit http://localhost:3000

These visualizations provide powerful insights into your microservices architecture, helping you understand dependencies, identify bottlenecks, and troubleshoot issues.


Monitoring and Observing Your Service Mesh with Kiali

After successfully deploying our microservices and generating some traffic by interacting with the ecommerce application, it's time to explore how Istio's observability tools provide insights into our service mesh. Kiali is an especially powerful visualization tool that helps us understand the topology, health, and traffic patterns of our services.

  1. Understanding the Kiali Interface

To access Kiali, run:

kubectl port-forward svc/kiali -n istio-system 20001

Then navigate to http://localhost:20001 in your browser.

  1. Applications View

The first image shows the Applications view in Kiali, which provides an overview of all deployed applications in our ecommerce namespace:

Here you can observe:

  • All seven of our microservices are healthy (indicated by green check marks)

  • Each application shows its labels (app=service-name, version=v1)

  • The Details column reveals that each service is properly connected to the ecommerce-gateway

  • The ecommerce-ui service has an additional ecommerce-gateway-routes VirtualService applied to it

This view confirms that all our microservices are properly deployed and configured within the service mesh.

  1. Workload Traffic Visualization

When you click on a specific application like "ecommerce-ui" (shown in the second image), Kiali displays a detailed traffic graph:

This visualization shows:

  • Traffic flowing from the istio-ingress gateway to the ecommerce-ui frontend

  • The frontend service communicating with multiple backend services

  • Response times (in milliseconds) for each service-to-service call

  • Traffic distribution percentages between services

Notice how the traffic flows from external users through the istio-ingress gateway into our ecommerce-ui frontend, which then communicates with various backend services as users navigate through the application. The graph reveals the actual service dependencies based on real traffic.

  1. Service Interactions

The third image shows a similar view for the order-management service:

Here we can see:

  • The order-management service receiving requests from the ecommerce-ui

  • Order-management sending requests to product-catalog and product-inventory

  • The response times for each service call

  • The traffic distribution percentages

This view helps us understand exactly how the order-management service interacts with other services when processing customer orders.

  1. Mesh Topology

The fourth image shows the Mesh view in Kiali:

This provides a high-level overview of the entire Istio infrastructure:

  • Kiali at the center as our visualization tool

  • Istiod as the control plane that manages service configuration

  • Prometheus for metrics collection

  • Grafana for metrics visualization

  • The overall data plane representing all service proxies

Implementing Canary Deployments with Istio

In this chapter, we'll explore how to implement a canary deployment strategy for our product catalog service using Istio's traffic management capabilities. This approach allows us to safely test a new version of our service with real users before fully committing to the change.

  1. Deploying the New Version

Let's start by deploying version 2 of our product catalog service alongside the existing version:

kubectl apply -f

This command applies several resources:

  1. A new product-catalog-v2 deployment with an updated image

  2. A MongoDB deployment to serve as the backend database

  3. Istio traffic management resources to control routing

  1. Generating Traffic to Both Versions

After deploying our new version, we need to generate some traffic to observe the canary deployment in action. We can do this by:

  1. Accessing the ecommerce UI through our browser at http://localhost:80

  2. Browsing the product catalog section

  3. Adding products to the cart

  4. Placing orders

As we interact with the application, Istio routes approximately 80% of requests to version 1 and 20% to version 2 of the product catalog service, as defined in our VirtualService configuration.

  1. Observing the Canary Deployment in Kiali

When we check Kiali, we can now see both versions of our product catalog service:

Notice how the product-catalog service now shows version=v1,v2 in its labels section, indicating that we have two versions of this service running simultaneously.

The traffic distribution between these versions can be observed in Kiali's traffic graph view, showing the 80/20 split we configured:

  1. Key Components of Our Canary Configuration

The canary deployment is made possible by two key Istio resources:

  1. DestinationRule: Defines the available versions (subsets) of our service

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: product-catalog
    spec:
      host: product-catalog
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version
    
    
  2. VirtualService: Controls the traffic split between versions

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: product-catalog
    spec:
      hosts:
      - product-catalog
      http:
      - route:
        - destination:
            host: product-catalog
            subset: v1
          weight: 80
        - destination:
            host: product-catalog
            subset: v2
          weight: 20
  1. Benefits of Canary Deployments

This approach offers several advantages:

  1. Risk mitigation: By exposing only a small percentage of traffic to the new version, we limit the impact of potential issues

  2. Real-world testing: We test the new version with actual users in production

  3. Gradual rollout: We can increase the traffic percentage to the new version as confidence grows

  4. Easy rollback: If issues are detected, we can quickly route 100% of traffic back to version 1

  1. Progressive Rollout Strategy

As we gain confidence in our new version, we can gradually increase its traffic weighting:

  1. Start with 20% traffic to v2 (current state)

  2. Monitor performance, errors, and user feedback

  3. If all metrics are positive, increase to 50/50

  4. Eventually shift to 0% v1, 100% v2

  5. When comfortable with the new version, remove the old version entirely


Implementing Circuit Breaking with Istio

In this chapter, we'll explore one of Istio's most powerful resiliency features: circuit breaking. This pattern prevents cascading failures in distributed systems by automatically detecting problematic services and temporarily routing traffic away from them.

  1. Deploying a Deliberately Faulty Service

Let's start by deploying a deliberately problematic version of our order-management service:

kubectl apply -f

This command deploys:

  1. An order-management-v2 deployment that intentionally lacks a MongoDB connection string, causing it to fail when attempting database operations

  2. A DestinationRule with circuit breaker settings

  3. A VirtualService that routes 80% of traffic to v1 and 20% to v2

  1. The Circuit Breaker Configuration

Our DestinationRule includes specific circuit breaker settings:

trafficPolicy:
  connectionPool:
    tcp:
      maxConnections: 100
    http:
      http1MaxPendingRequests: 10
      maxRequestsPerConnection: 10
  outlierDetection:
    consecutive5xxErrors: 5
    interval: 30s
    baseEjectionTime

The critical component here is outlierDetection, which:

  • Monitors for 5 consecutive errors

  • Checks for failures every 30 seconds

  • Ejects problematic instances for 30 seconds before retrying

  1. Observing Circuit Breaking in Action

After deploying, let's interact with our ecommerce application. Initially, when you try placing orders, you'll experience intermittent failures as approximately 20% of requests route to the faulty v2 service.

Looking at the order-management-v2 workload in Kiali, we can see:

  • The lightning bolt icons indicating circuit breaker activation

  • 100% inbound error rate for traffic to this service

  • Red connection lines showing the error paths

  • The pod is running (green status indicator) but functionally failing

The circuit breaker detects these consistent failures and begins to take action. After 5 consecutive errors, the circuit "trips" and the faulty v2 instance is ejected from the load balancing pool.

  1. Viewing the Overall Traffic Flow

The traffic graph provides a clear visualization of errors propagating through order-management-v2:

Notice the key indicators:

  • Red lines showing a 28% error rate between ecommerce-ui and order-management

  • Lightning bolt icons marking where circuit breakers have activated

  • The 5.5s average response time for problematic connections

  • Green connections to other services like product-catalog, which remain healthy

  1. Recovery Through Circuit Breaking

After about 5 minutes of continued interaction with the application, you'll notice something interesting - the order placement feature starts working reliably. Looking at the Kiali graph:

Look at the highlighted area in the image - now we see:

  • Green connection lines to order-management

  • Improved response times (6.5s)

  • No more error indicators

  • Higher throughput (96bps)

This improvement occurs because Istio's circuit breaker has:

  1. Identified order-management-v2 as consistently failing

  2. Ejected it from the load balancing pool

  3. Rerouted all traffic to the healthy order-management-v1 instance

While the original traffic split was configured for 80/20, the circuit breaker has effectively modified this to 100/0 until the problematic service recovers.

  1. Benefits of Circuit Breaking

This demonstration highlights several key advantages:

  1. Automatic failure detection: Istio identifies problematic services without human intervention

  2. Fault isolation: Failures in one component don't cascade to the entire system

  3. Self-healing: The system recovers automatically by routing around failures

  4. Periodic retries: After 30 seconds, Istio attempts to use the service again to check if it has recovered

  5. Improved user experience: End users see fewer errors as the system adapts


Monitoring Your Istio Service Mesh with Grafana

In this chapter, we'll explore how to use Grafana to monitor the health and performance of our Istio service mesh. Grafana provides powerful visualization capabilities for metrics collected by Prometheus, giving you deep insights into your microservices application.

  1. Accessing the Grafana Dashboard

Now that we've seen how our circuit breaker functions in Kiali, let's examine the performance metrics of our services in more detail. Start by port-forwarding the Grafana service:

kubectl port-forward svc/grafana -n istio-system 3000

Then navigate to http://localhost:3000 in your browser. The default login is:

  • Username: admin

  • Password: admin

  1. Exploring Istio Dashboards

Grafana comes pre-configured with several specialized Istio dashboards. Let's explore each one to understand what insights they provide:

  1. Istio Mesh Dashboard

This dashboard provides a high-level overview of all services in your mesh:

  • Global request volume and success rates

  • Service mesh-wide latency metrics

  • HTTP/TCP/gRPC metrics across all services

  • Service health at a glance

Use this dashboard to quickly assess the overall health of your entire service mesh.

  1. Istio Service Dashboard

Focused on individual services, this dashboard shows:

  • Client and server-side metrics for a specific service

  • Request rates, error rates, and latency

  • Detailed breakdown of HTTP status codes

  • Incoming and outgoing connections

This view is particularly useful when investigating issues with specific services like our order-management service during circuit breaking events.

  1. Istio Workload Dashboard

This dashboard focuses on individual workloads (deployments/pods):

  • Client and server metrics at the workload level

  • Detailed traffic patterns for specific versions

  • Resource utilization by workload

  • TCP/HTTP connection metrics

Use this to compare the performance between different versions of the same service, such as product-catalog-v1 vs product-catalog-v2.

  1. Istio Control Plane Dashboard

Monitors the health of Istio's own components:

  • istiod resource utilization

  • Control plane performance metrics

  • Configuration validation success/failure rates

  • Discovery service metrics

This dashboard helps ensure that Istio itself is operating efficiently.

  1. Istio Performance Dashboard

Focuses on the performance overhead of the Istio service mesh:

  • Proxy resource consumption

  • Control plane performance

  • Data plane overhead

  • Service latency attribution

This is crucial for understanding how Istio impacts your overall system performance.

  1. How to Use These Dashboards Effectively

When troubleshooting issues in your service mesh:

  1. Start with the Mesh Dashboard to identify if there's a system-wide issue

  2. Drill down to the Service Dashboard for the specific service showing problems

  3. Check the Workload Dashboard to compare different versions of a service

  4. Use the Performance Dashboard if you suspect Istio overhead is causing issues

For our ecommerce application, pay particular attention to:

  • Success rate drops for the order-management service

  • Latency spikes when the circuit breaker activates

  • Traffic shifting patterns when failures are detected

  • Resource utilization during peak traffic

Distributed Tracing: Current Jaeger Implementation

While we've focused primarily on metrics and service visualization, Istio also includes Jaeger for distributed tracing. Though we haven't configured our applications to propagate trace headers, we can still explore what Jaeger offers in our environment.

  1. Accessing Jaeger

To explore our current Jaeger setup, access it through port-forwarding:

kubectl port-forward svc/tracing -n istio-system 16686

Then navigate to http://localhost:16686 in your browser.

  1. What Our Jaeger Currently Shows

With our current implementation, Jaeger already captures some basic information:

  • Service List: You'll see all our services (ecommerce-ui, product-catalog, order-management, etc.)

  • Limited Traces: Some traces are captured, but they're fragmented and don't show the complete request journey

  • Infrastructure Traffic: Most visible traces are from Istio's own components like istiod and the ingress gateway

  • Missing Connections: The connections between our services are incomplete due to missing propagation headers

  1. Why Our Traces Are Limited

Our current traces are limited because we haven't:

  1. Added the necessary trace context propagation headers in our services

  2. Configured appropriate sampling rates

  3. Instrumented our applications with OpenTelemetry or similar frameworks


  4. The Missing Piece

For complete distributed tracing, our services would need to forward trace headers like:

  • x-request-id

  • x-b3-traceid

  • x-b3-spanid

  • x-b3-parentspanid

These headers maintain the causal relationship between requests across service boundaries.

  1. The Value of Complete Distributed Tracing

With proper trace propagation, Jaeger would show:

  • Full Request Paths: The exact sequence of service calls for each user action

  • Precise Timing: Detailed timing information for each step in the request flow

  • Error Chains: How errors propagate from one service to another

  • Bottleneck Identification: Services or operations causing latency issues

  • Unexpected Dependencies: Hidden service relationships not evident from code

This visibility would be particularly valuable for debugging complex patterns like circuit breaking, where understanding the complete request context can make troubleshooting significantly easier.

Conclusion

Throughout our journey with Istio, we've built a robust microservices architecture with powerful capabilities for traffic management, resilience, and observability. From canary deployments to circuit breaking, from visualizing service interactions in Kiali to monitoring performance metrics in Grafana, Istio provides the tools needed to confidently operate complex distributed systems in production environments.

Want to become cloud-native?

Master Kubernetes with our Complete Course: https://www.udemy.com/course/kubernetes-bootcamp-kubernetes-from-zero-to-cloud/?couponCode=FRAMER_3

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates