Ambient mode is Istio’s way of ditching sidecars for much of your traffic, but it’s not just a simpler config. It fundamentally changes how Istio intercepts and manages network traffic.

Let’s see it in action. Imagine you have a simple service, my-app, running in Kubernetes. Normally, you’d annotate its deployment to inject a sidecar. With Ambient, you don’t.

Here’s a Deployment for my-app without the Istio sidecar injection annotation:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: nginx:latest # Replace with your actual application image
        ports:
        - containerPort: 80

In Ambient, Istio introduces two new components that handle traffic outside of your application pods: the istio-ingressgateway (which you might already have) and the istiod control plane. Crucially, Istio also deploys ztunnel pods in your application’s namespace (or a dedicated istio-system namespace if configured). These ztunnel pods are the workhorses of Ambient mode.

When traffic enters a pod managed by Ambient, it doesn’t hit a sidecar. Instead, it’s intercepted by the ztunnel in that pod’s namespace. The ztunnel is responsible for applying Istio policies, such as mTLS, traffic routing, and telemetry collection, before forwarding the traffic to the actual application container. For outbound traffic from your application, the ztunnel intercepts it, applies policies, and then routes it to its destination.

The key difference here is that the ztunnel acts as a network proxy for your pods, not an application proxy within the pod like the traditional sidecar. This means your application doesn’t need to be aware of Istio’s presence at all. It just binds to its port, and the ztunnel handles the rest.

To enable Ambient mode, you’ll need to configure Istio’s control plane. This typically involves setting the meshConfig.defaultConfig.proxyProtocol to ambient in your Istio operator configuration or istiod deployment.

Here’s an excerpt from an Istio operator configuration to enable Ambient:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      proxyProtocol: ambient
    enableAmbient: true

Once Istio is installed or upgraded with this configuration, you’ll see ztunnel pods running in your namespaces.

The problem Ambient solves is the operational overhead and resource consumption of injecting sidecars into every application pod. By moving the proxy logic to dedicated ztunnel pods, Istio reduces the CPU and memory footprint on your application nodes and simplifies application deployment. You can opt-in services to Ambient gradually, or even run a mixed mode where some services have sidecars and others use Ambient.

The ztunnel itself uses Envoy, but it’s configured differently. Instead of being injected as a sidecar, it’s deployed as a standalone proxy. It listens on the network interfaces of the node or pod and intercepts traffic based on Kubernetes network policies and Istio’s configuration. For a pod in Ambient mode, its traffic is routed to the ztunnel within its namespace, and the ztunnel then forwards it to the destination pod.

The istio-ingressgateway also plays a role. When traffic enters the mesh from outside, it first hits the ingress gateway. If Ambient is enabled, the ingress gateway can be configured to send traffic directly to services in Ambient mode, again without requiring sidecars on those services.

The most surprising thing about Ambient mode is that your application doesn’t need to know how its traffic is being proxied. It just sends traffic to localhost:PORT. The ztunnel intercepts this, applies all Istio features (mTLS, traffic policies, etc.), and then routes it. This means you can adopt Istio features without modifying your application code or deployment manifests for sidecar injection.

The ztunnel operates at the network layer, meaning it intercepts TCP and UDP traffic. It doesn’t understand application-level protocols like HTTP or gRPC directly. Instead, it relies on Istio’s control plane (istiod) to tell it how to handle traffic based on the service it’s destined for. istiod pushes the relevant Envoy configuration to the ztunnel for each service, allowing it to perform L7 routing, security, and telemetry functions based on the destination.

The final piece of the puzzle is how Istio manages traffic between services in Ambient mode. When service A wants to talk to service B, and both are in Ambient mode, the traffic from service A is intercepted by its local ztunnel. This ztunnel then forwards the traffic, potentially over the network, to the ztunnel associated with service B’s pod. The destination ztunnel then forwards the traffic to service B’s actual application container. This inter-ztunnel communication is where Istio’s routing and security policies are enforced.

The next thing you’ll grapple with is how to selectively enable Ambient for specific services while others retain their sidecars.

Want structured learning?

Take the full Istio course →