Ambient mode in Istio fundamentally changes how traffic flows, and ztunnel is the new, slimmed-down data plane component that handles plain TCP and plain HTTP traffic before it even hits a workload.
Here’s ztunnel in action, processing traffic that’s destined for a reviews service in the default namespace. Notice how it’s not a full Envoy proxy anymore; it’s lightweight, focusing on essential transport-level operations.
# Simulate a request from a client pod to the reviews service
kubectl exec -n default deploy/webapp -- curl -s reviews:9080/reviews/1
# Observe ztunnel logs (this would be a real log in a cluster)
# In a real scenario, you'd grep these logs from the ztunnel pod
# Example log snippet showing ztunnel processing the request:
# 2023-10-27T10:00:00.123Z INFO inbound|9080|10.1.0.5|reviews.default.svc.cluster.local connection from 10.1.1.2:54321
# 2023-10-27T10:00:00.125Z INFO outbound|9080|10.1.0.5|reviews.default.svc.cluster.local forwarding to 10.1.0.5:9080
The core problem Istio ambient mode, and ztunnel within it, solves is the complexity and overhead of traditional sidecar proxies. Instead of injecting a full Envoy proxy into every application pod, ambient mode uses a shared ztunnel and istiod (for control plane functions). ztunnel sits at the network boundary of a pod, acting as a transparent interceptor. For inbound traffic, it inspects and routes it. For outbound traffic, it intercepts and directs it, applying security policies and telemetry collection. This means workloads don’t need to be modified, and the resource footprint per pod is drastically reduced.
The mental model for ambient mode involves two main components: ztunnel and the application pod. ztunnel is the gatekeeper. All traffic entering a pod’s network namespace and all traffic leaving a pod’s network namespace is routed through ztunnel. ztunnel then makes decisions based on Istio’s configuration, which it receives from istiod. If the traffic is for a workload within the mesh, ztunnel routes it to the correct pod. If it’s external, it handles it accordingly. Security policies, like authorization and mTLS, are enforced by ztunnel before the traffic even reaches the application.
Here’s a look at the configuration for enabling ambient mode and a typical ztunnel deployment:
# Istio operator configuration to enable ambient mode
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
ambient:
enabled: true
pilot: # Pilot is still needed for control plane functionality
enabled: true
values:
meshConfig:
enableEnvoyFilter: true # Often needed for advanced configurations
defaultConfig:
# Default proxy configuration, ztunnel inherits this
proxyMetadata:
ISTIO_META_AUTO_SESSION_LOCAL_METADATA: "true"
The ztunnel itself is deployed as a DaemonSet, ensuring a ztunnel instance runs on every node in the cluster. This node-local deployment is key to its efficiency. It intercepts traffic at the node level for pods on that node.
# Example ztunnel deployment (simplified for illustration)
# This is managed by the Istio operator but shows the underlying structure
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: istio-ztunnel
namespace: istio-system
spec:
template:
spec:
containers:
- name: ztunnel
image: istio/ztunnel:1.20.0 # Example image version
args:
- "istiod" # ztunnel runs as a proxy, not directly istiod
- "data-plane"
- "--logtostderr"
# ... other configuration flags ...
# ... node selector, tolerations, etc. ...
The beauty of ztunnel is its minimal footprint for plain TCP/HTTP. It doesn’t have the full feature set of an Envoy sidecar (like advanced L7 routing rules within the proxy itself, or complex WASM extensions). Instead, it focuses on the core tasks: network interception, basic L4/L7 protocol detection, mTLS termination/origination, and forwarding based on istiod’s directives. For more sophisticated L7 routing or policy enforcement, Istio’s ambient mode introduces the istio-ingressgateway and istio-egressgateway as L7 proxies, and istiod orchestrates the entire flow.
One aspect of ambient mode that catches people off guard is how it handles non-HTTP/TCP traffic. ztunnel is designed to pass through arbitrary TCP traffic by default, but it doesn’t inspect or apply L7 policies to it. If you need to secure or manage non-HTTP/TCP traffic with advanced Istio features (like specific authorization policies based on payload, or detailed telemetry), you’ll likely need to leverage a more traditional sidecar for those specific workloads, or configure dedicated L7 gateways that can handle those protocols.
The next hurdle you’ll encounter after successfully enabling and configuring ambient mode is understanding how to apply fine-grained L7 authorization policies to services that were previously managed by sidecars, especially when those policies are complex and require inspecting the request payload.