The sidecar era is ending
Service mesh has always been a good idea with a difficult implementation. mTLS between services, traffic shaping, observability without code changes. All things you want. But the sidecar model that powered Istio for years came with a real bill: resource overhead at pod level, lifecycle coupling between the mesh and your applications, injection webhooks that could quietly fail, and mesh upgrades that required rolling restarts of every workload in the cluster.
Istio Ambient mode reached general availability in Istio 1.24 (current release is 1.29) and changes the architecture entirely. No sidecars. No injection. Two dedicated proxy layers instead of one proxy per pod. If you’re new to service mesh and evaluating your options, this is where I’d tell you to start.
What a service mesh actually does
Before the architecture, the job. A service mesh gives you three things that are hard to get any other way.
Mutual TLS between services. Every pod-to-pod connection is encrypted and both sides are authenticated. Not just the server, but the client too. In a cluster without a mesh, a compromised pod can impersonate any other service. With mTLS and cryptographic workload identity, it cannot.
Traffic control without code changes. Retry policies, timeouts, circuit breakers, canary routing. All configurable at the control plane, not baked into application code. Your services don’t need to know the mesh exists.
Observability for free. Latency metrics, request rates, error rates, distributed traces. All emitted by the mesh layer before a request reaches your application code. You get a unified picture across the whole cluster without instrumenting each service individually.
These are real capabilities that take significant engineering effort to replicate at the application layer. That’s why service mesh adoption grew even as the operational costs were high.
The sidecar problem
The dominant model for service mesh has been the sidecar: an Envoy proxy injected as an additional container into every application pod. Istio’s original data plane is built entirely on this model.
Sidecars work. They put the proxy close to the application, provide per-pod isolation, and handle traffic interception via iptables rules inside the pod network namespace. For teams that could absorb the overhead, they were a proven production model.
But the costs add up.
Resource overhead per pod. Every meshed pod carries an Envoy sidecar consuming memory and CPU regardless of traffic volume. At pod-heavy scale (hundreds or thousands of workloads) this becomes real cluster cost. The sidecar sits idle most of the time and still draws resources.
Lifecycle coupling. The sidecar lives inside the pod. When you upgrade the mesh (version bumps, certificate rotation, policy changes) you need to rolling-restart your application pods to pick up the new proxy. Mesh operations bleed directly into application operations.
Injection complexity. Sidecar injection happens via a mutating admission webhook. If the webhook is misconfigured or unavailable at pod scheduling time, pods can start without a sidecar, silently breaking your mTLS guarantees. Getting injection right across namespaces, exclusions, init containers, and iptables rules is operationally fiddly.
Blast radius on misconfiguration. A bad EnvoyFilter or misconfigured VirtualService can affect every workload carrying that proxy config. The mesh is everywhere, so its failures are everywhere too.
Ambient mode was designed to address every one of these.
Enter Ambient
Announced in 2022 by Google and Solo.io, Ambient mode reached general availability in Istio 1.24. It is not a different product. It is a different data plane model for the same Istio control plane you already know.
The core insight is a separation of concerns that sidecar mode never made: L4 and L7 are different problems that deserve different solutions.
L4 (mTLS, workload identity, basic authorization, telemetry) applies to all traffic, all the time, for every workload in the mesh. It is universal and relatively cheap. L7 (HTTP routing, header manipulation, JWT validation, fine-grained authorization) is more expensive to process and only a subset of workloads actually need it. Treating them the same by stuffing both into a sidecar was the architectural mistake.
Ambient separates them into two independent layers. No sidecars required for either.
Architecture
The two data plane layers
Ambient’s data plane has two layers that operate independently and at different scopes.
The L4 layer is mesh-wide and always-on. Every workload enrolled in ambient mode gets mTLS, workload identity, L4 policy enforcement, and telemetry automatically, with no per-workload deployment.
The L7 layer is opt-in, scoped to a namespace or service account. You deploy it only where you need advanced HTTP capabilities. If a service does not require JWT validation or header-based routing, it pays nothing for L7 processing.

ztunnel: the L4 foundation
The ztunnel (zero-trust tunnel) is a DaemonSet: one instance per node, written in Rust, purpose-built for Ambient mode. It handles everything at L4. mTLS establishment, workload identity via SPIFFE certificates, L4 authorization policy, and telemetry collection.
Traffic interception works through the Istio CNI plugin, which monitors pod lifecycle events and configures traffic redirection from pods on the node to the local ztunnel socket. No init containers, no per-pod iptables injection.
When two pods on different nodes communicate, the source ztunnel opens an HBONE tunnel to the destination ztunnel, carrying the connection with full mTLS and embedded SPIFFE identity. The application pods see none of this. From their perspective, they make a normal outbound connection and receive a normal inbound one.
ztunnel is deliberately narrow in scope. It does not parse HTTP. It does not inspect application payloads. It handles the cryptographic and identity layer efficiently, shared across all pods on the node.
Waypoint proxies: L7 on demand
Waypoint proxies are Envoy-based proxies deployed per namespace or per service account. They are entirely optional. You only deploy one where your workloads need L7 capabilities.
When a waypoint is present for a destination, the source ztunnel forwards traffic to the waypoint instead of directly to the destination ztunnel. The waypoint handles L7 policy (HTTP routing, retries, header manipulation, JWT validation, AuthorizationPolicy with HTTP attributes) then forwards to the destination ztunnel, which delivers to the target pod. Policy enforcement is destination-side only, which makes reasoning about what policy applies to a workload straightforward.
Waypoints are created using the Kubernetes Gateway API, which is the right abstraction: the mesh’s L7 infrastructure becomes a programmable gateway, not an opaque mesh-internal component. This aligns Istio’s L7 layer with the broader Kubernetes networking ecosystem.
Because waypoints are per namespace or service account rather than per pod, policy has a clear enforcement boundary. There is no web of per-pod proxies each enforcing a different subset of rules. There is one waypoint that is the authoritative enforcement point for its domain.
Control plane: istiod
The control plane does not change. Istiod continues to handle service discovery, configuration distribution, and certificate management. It issues SPIFFE certificates to both ztunnels and waypoints, and pushes configuration to both layers.
What changes is the xDS API used to program ztunnels: it is a leaner, ztunnel-specific API rather than full Envoy xDS. Waypoints continue to receive standard Envoy xDS. Both remain consistent with the control plane model that Istio operators already understand. There is no new control plane to operate.
Key terminology
Ambient mode: Istio’s sidecar-free data plane model. Uses ztunnel for L4 and optional waypoint proxies for L7 instead of per-pod Envoy sidecars.
HBONE (HTTP-Based Overlay Network Environment): The tunneling protocol used between Ambient components. HTTP/2 CONNECT tunneling with mTLS, operating on port 15008. Carries SPIFFE workload identity across network hops.
ztunnel: The per-node DaemonSet proxy (Rust) providing L4 mTLS, identity, authorization policy, and telemetry. The always-on, zero-overhead base layer of the mesh.
Waypoint proxy: An optional per-namespace or per-service-account Envoy proxy for L7 traffic policy. Deployed via Kubernetes Gateway API. Only present where L7 features are needed.
SPIFFE / SVID: The identity standard embedded in all workload certificates. Each pod’s identity takes the form spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>, tied to its Kubernetes service account. This is what makes mTLS meaningful. Identity is cryptographic and bound to Kubernetes RBAC, not to an IP address that could be reused.
Istio CNI: The CNI plugin that monitors pod lifecycle events and configures traffic redirection from workloads to the local ztunnel. Replaces the privileged init container used in sidecar mode.
Gateway API: A collection of Kubernetes APIs for traffic routing and management. Ambient uses Gateway API to configure waypoint proxies, aligning with the broader Kubernetes networking ecosystem.
xDS: The data plane configuration API that istiod uses to push configuration to ztunnels and waypoints. ztunnel receives a leaner, purpose-built xDS variant while waypoints use standard Envoy xDS.
Getting started
This section walks through the core installation steps. A future post will cover installation best practices, production hardening, and upgrade strategies in depth.
Prerequisites
Ambient mode requires Kubernetes 1.26 or later. You also need the Gateway API CRDs installed. Most clusters don’t have these by default:
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yaml
The experimental channel is required for some Istio features. Check the Gateway API releases for the latest version.
Installing istiod and ztunnel
Install Istio with the ambient profile. This deploys istiod (control plane), ztunnel (L4 DaemonSet), and the Istio CNI plugin:
istioctl install --set profile=ambient --skip-confirmation
The ambient profile configures:
- istiod in the
istio-systemnamespace, handling service discovery, certificate issuance, and xDS configuration - ztunnel as a DaemonSet, one pod per node, providing L4 mTLS and telemetry
- Istio CNI as a DaemonSet, configuring traffic redirection from application pods to ztunnel
Verify the installation:
kubectl get pods -n istio-system
You should see istiod, ztunnel pods (one per node), and istio-cni-node pods (one per node).
Enrolling workloads
Adding workloads to the mesh is a namespace label:
kubectl label namespace default istio.io/dataplane-mode=ambient
Every pod in that namespace now has L4 mTLS, workload identity, and telemetry. No restarts, no injection, no configuration beyond the label. Existing pods pick it up immediately. The CNI plugin detects the label and redirects traffic through ztunnel.
Verify mTLS is active by checking ztunnel logs or using istioctl proxy-config on the ztunnel pods.
Deploying waypoints for L7
Waypoints are optional. Deploy one only when you need L7 features like HTTP routing, retries, JWT validation, or L7 authorization policies.
Create a waypoint for a namespace:
istioctl waypoint apply --namespace default --enroll-namespace
This creates a Gateway resource and a waypoint Deployment in the namespace. The --enroll-namespace flag automatically labels the namespace to use this waypoint.
You can also create waypoints scoped to specific service accounts:
istioctl waypoint apply --namespace default --service-account my-service
Traffic destined for pods running as my-service will route through this waypoint.
List waypoints:
istioctl waypoint list
Remove a waypoint:
istioctl waypoint delete --namespace default
When no waypoint is present, traffic flows through ztunnel only (L4). When a waypoint exists and the namespace or service account is enrolled, traffic routes through the waypoint for L7 processing before reaching the destination.
What Ambient gets right
No app restarts for mesh operations. ztunnel upgrades happen at the node level, decoupled from your application pods. Mesh maintenance stops bleeding into application downtime windows.
Zero injection friction. No mutating webhook. No init containers. No iptables debugging inside pod network namespaces. Enroll a namespace and the CNI plugin handles the redirection. Unenroll it and the mesh steps out entirely.
Progressive adoption. Start with L4: free mTLS and telemetry across every enrolled workload, with no per-service configuration. Add a waypoint only where you need HTTP routing or fine-grained authorization. Pay for exactly what you use.
Correct abstraction boundary. The mesh is infrastructure. Ambient treats it as infrastructure. Your application pods carry no mesh component. They are just workloads. The mesh lives at the node and namespace level, where infrastructure belongs.
Lower resource floor. No per-pod Envoy sidecars. The ztunnel DaemonSet is shared across every pod on a node. At any meaningful workload density, the resource difference relative to sidecars is substantial. Solo.io provides a cost savings estimator if you want to model your own environment.
What to watch
Ambient reached GA with a solid and growing feature set. These are known gaps to understand before committing.
Feature coverage from sidecar mode. If you are migrating an existing Istio deployment, verify that your specific EnvoyFilter customizations or traffic management features translate to the Ambient model. Most production patterns are covered, but advanced low-level Envoy customizations behave differently when the proxy is a waypoint rather than a sidecar.
Distributed tracing scope. Ambient currently captures Istio component spans rather than application-level spans. If your observability pipeline depends on sidecar-emitted spans to propagate trace context automatically, validate your tracing setup before migrating. This is an area under active development.
Platform and CNI compatibility. The Istio CNI plugin requirement means your underlying CNI implementation and cloud provider’s managed Kubernetes offering need to support it. Check the Istio compatibility matrix for your environment before a production rollout.
None of these are blockers for new deployments. They are known quantities with documented scope, not surprises.
The verdict
If you are evaluating service mesh for the first time today, start with Ambient. The sidecar model existed because there was no better option at the time. There is one now.
The architecture is cleaner: two focused layers with clear separation of concerns, no per-pod overhead, and independently managed lifecycles. The operational model is simpler: label a namespace, add a waypoint when you need L7, upgrade the mesh without touching your applications. The abstraction is right: infrastructure that stays out of your workloads.
The GA designation in Istio 1.24 was not a preview label. Five releases later (1.29 at time of writing), Ambient is production-ready with mature migration tooling for teams running sidecars.
Start here.
Coming up
This post covers the concepts and architecture at a level that should give you a working mental model. Each component deserves more depth. Future posts will go deep on ztunnel internals, how HBONE tunneling works at the protocol level, configuring waypoints with the Gateway API, L7 policy in practice, observability in ambient mode, and the migration path from sidecar deployments.
Resources
- Istio Ambient Mode Documentation - official docs, installation guides, and reference
- ambientmesh.io - dedicated site with architecture deep dives, cost calculator, and getting started guides
Comments