Skip to content
Istio Ambient Mesh: A Deep Dive into Ztunnel and Waypoint Proxies

Istio Ambient Mesh: A Deep Dive into Ztunnel and Waypoint Proxies

March 10, 2026

Background: The Sidecar Tax

The classic Istio sidecar model — injecting an Envoy proxy into every pod — has been the dominant service mesh architecture for years. It provides powerful capabilities: mTLS, traffic management, observability. But it comes with real costs:

  • Memory overhead: Each Envoy sidecar consumes 50–150 MB of RAM
  • CPU tax: Proxy interception adds latency and burns CPU cycles
  • Operational complexity: Sidecar lifecycle is tied to pod lifecycle; rollouts require pod restarts
  • Slow adoption: Teams must opt individual namespaces into the mesh

Istio Ambient Mesh, graduated to stable in Istio 1.22, fundamentally changes this model.

The Ambient Architecture

Ambient introduces a two-layer proxy architecture:

┌─────────────────────────────────────────────────────────────┐
│  Kubernetes Node                                             │
│                                                             │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐               │
│  │  Pod A   │   │  Pod B   │   │  Pod C   │               │
│  │ (no sidecar) │ (no sidecar) │ (no sidecar)              │
│  └────┬─────┘   └────┬─────┘   └────┬─────┘               │
│       │              │              │                       │
│       └──────────────┴──────────────┘                      │
│                       │                                     │
│              ┌────────▼────────┐                           │
│              │    Ztunnel      │  ← Layer 4 (per node)     │
│              │  (per node DaemonSet)│                       │
│              └────────┬────────┘                           │
└───────────────────────┼─────────────────────────────────────┘
                        │
              ┌─────────▼─────────┐
              │  Waypoint Proxy   │  ← Layer 7 (per service)
              │  (Envoy, on-demand)│
              └───────────────────┘

Ztunnel: The L4 Foundation

Ztunnel is a purpose-built, lightweight Rust proxy deployed as a DaemonSet — one per node. It handles:

  • mTLS establishment using SPIFFE certificates from the Istiod CA
  • L4 policy enforcement (authorization by source/destination identity)
  • Transparent traffic interception via eBPF or iptables
  • HBONE tunneling (HTTP-Based Overlay Network Encapsulation)

Crucially, Ztunnel does not do L7 processing. It understands TCP flows, not HTTP routes.

# Check Ztunnel status on a node
kubectl get pods -n istio-system -l app=ztunnel

# View Ztunnel config dump (xDS state)
kubectl exec -n istio-system ztunnel-xxxxx -- curl -s localhost:15000/config_dump | jq .

Waypoint Proxies: On-Demand L7

When you need HTTP routing, retries, fault injection, or L7 authorization, you deploy a Waypoint proxy — a standard Envoy instance scoped to a service account or namespace.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: waypoint
  namespace: bookinfo
  labels:
    istio.io/waypoint-for: service
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE

The key insight: Waypoints only exist when you need them. If your service only needs mTLS and L4 identity, Ztunnel handles it with near-zero overhead. Waypoints are created on demand for services requiring L7 policies.

Traffic Flow Walkthrough

Here’s how a request from Pod A to Service B flows in Ambient mode:

  1. Pod A sends a normal TCP connection to Service B’s cluster IP
  2. Ztunnel on Node A intercepts via eBPF, wraps in HBONE tunnel, adds SPIFFE identity headers
  3. Ztunnel on Node B receives the HBONE tunnel, verifies the peer certificate
  4. If Service B has a Waypoint, Ztunnel forwards to it for L7 processing; otherwise delivers directly to Pod B
  5. Waypoint applies HTTPRoute policies, retries, circuit breaking, etc.
  6. Response flows back through the same path

Resource Comparison

ModelMemory per podCPU overheadRestart required for config?
Sidecar50–150 MB~5–10ms/reqYes (pod restart)
Ambient (Ztunnel only)~0 MB~1–2ms/reqNo
Ambient + Waypoint~0 MB per pod~3–5ms/reqNo

Enabling Ambient Mode

# Install Istio with ambient profile
istioctl install --set profile=ambient

# Label a namespace for ambient
kubectl label namespace bookinfo istio.io/dataplane-mode=ambient

# Verify pods are enrolled (no sidecar injection)
kubectl get pods -n bookinfo
# You'll see no istio-proxy containers — but traffic is still encrypted

Limitations to Know

  1. No per-pod policies: Ztunnel is per-node; if you need per-pod L7 policies, use Waypoints scoped to service accounts
  2. HBONE compatibility: East-west traffic uses HBONE; ensure firewall rules allow port 15008
  3. Egress gateways: Still use traditional Envoy gateways for egress
  4. Multicluster: Ambient multicluster support is still maturing as of Istio 1.24

When to Choose Ambient

Choose Ambient if:

  • You have high pod density and sidecar memory costs are significant
  • You want gradual mesh adoption without pod restarts
  • Your use case is primarily mTLS + basic L4 policy

Stick with sidecars if:

  • You need per-pod L7 telemetry granularity
  • Your team is deeply invested in sidecar-specific tooling
  • You’re on Istio < 1.22

Conclusion

Ambient Mesh represents a maturation of the service mesh concept — separating concerns between L4 connectivity (cheap, always-on) and L7 policy (powerful, on-demand). For most greenfield deployments, it’s now the recommended starting point.


Next in the series: Debugging HBONE tunnels with Ztunnel’s built-in diagnostics.