Istio’s observability features don’t just show you what’s happening; they fundamentally change how you reason about distributed systems by making the invisible explicit.

Let’s see it in action. Imagine a simple request flowing through two services, frontend and backend, both managed by Istio.

# Istio gateway configuration
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: frontend-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
# Istio virtual service for frontend
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: frontend
spec:
  hosts:
  - frontend
  gateways:
  - frontend-gateway
  http:
  - route:
    - destination:
        host: frontend
---
# Istio destination rule for frontend
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: frontend
spec:
  host: frontend
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---
# Istio virtual service for backend (called by frontend)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
spec:
  hosts:
  - backend
  http:
  - route:
    - destination:
        host: backend
---
# Istio destination rule for backend
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: backend
spec:
  host: backend
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

When a request hits the frontend-gateway, Istio’s ingress controller intercepts it. It injects tracing headers and forwards the request to the frontend service, which is now running with a sidecar proxy (Envoy). The frontend service, in turn, makes a call to the backend service. Again, the frontend’s sidecar intercepts this outgoing request, adds tracing information, and sends it to the backend’s sidecar. The backend’s sidecar then forwards the request to the backend application.

Istio’s observability suite provides three core pillars:

  1. Metrics: Envoy proxies generate detailed metrics for every request and response. These include request volume, latency (95th percentile, 99th percentile), success rates (HTTP 2xx, 3xx, 4xx, 5xx), and more. Tools like Prometheus scrape these metrics from the Envoy sidecars.

    • Command to view metrics: kubectl exec $(kubectl get pod -l app=frontend -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -- curl localhost:15020/stats/prometheus
    • This command accesses the Envoy admin interface on port 15020 within the frontend pod, specifically requesting metrics in Prometheus format.
  2. Distributed Tracing: Istio automatically propagates tracing headers (like x-request-id, x-b3-traceid, x-b3-spanid) across service calls. When a request travels from frontend to backend, the tracing context is passed along. This allows you to reconstruct the entire path of a request, showing each hop and its duration. Tools like Jaeger or Zipkin collect and visualize these traces.

    • Command to enable tracing: Ensure tracing is enabled in your Istio operator configuration or IstioOperator resource. For example, in IstioOperator:
      apiVersion: install.istio.io/v1alpha1
      kind: IstioOperator
      spec:
        meshConfig:
          enableTracing: true
          defaultConfig:
            tracing:
              zipkin:
                address: zipkin.istio-system:9411
      
    • This configuration tells Istio to enable tracing and send spans to the Zipkin collector at zipkin.istio-system:9411.
  3. Access Logs: Envoy proxies log details about each request they handle. These logs include source and destination IPs, ports, HTTP method, URL, response code, latency, and bytes transferred. These logs are typically collected by a logging agent (like Fluentd or Filebeat) and sent to a central logging system (like Elasticsearch or Loki).

    • Viewing access logs (example with kubectl logs): While not ideal for production, you can see raw logs from the proxy. kubectl logs <frontend-pod-name> -c istio-proxy
    • This command retrieves the standard output from the istio-proxy container within a specific pod, which often includes access log information if configured.

The real power comes when you correlate these signals. A spike in 5xx errors in Prometheus for the backend service can be investigated with distributed tracing to pinpoint which specific requests failed and why (e.g., a slow upstream call, a specific error code from a downstream dependency). Access logs provide the granular detail for individual requests when tracing isn’t enough.

What most people don’t realize is that Istio doesn’t generate all this observability data itself; it leverages the Envoy sidecar proxy’s capabilities. Envoy is the workhorse, meticulously tracking every network hop, and Istio’s control plane configures Envoy to export this data in standardized formats for Prometheus, Zipkin/Jaeger, and logging backends. This abstraction means you get consistent observability across all your services, regardless of their language or framework, as long as they are injected with an Istio sidecar.

The next logical step is to start using these signals for automated policy enforcement and anomaly detection, moving beyond just passive monitoring.

Want structured learning?

Take the full Istio course →