January 29, 2024·6 min read·engineeringistioambientnetworking

Ambient traffic capture moves inside the pod network namespace

Istio's new ambient capture model keeps ztunnel outside application pods while placing its listening sockets inside their network namespaces. This avoids host-level routing conflicts with the primary CNI.

Ambient mesh's initial traffic-capture design competed with the component already responsible for Kubernetes networking. Its redirection rules lived in the host network namespace, where the primary CNI also needed to control packet routing. The January 29 design article describes a replacement that moves capture into each application pod's network namespace. The ztunnel process remains outside the application pod, but its listening sockets can exist inside that pod's networking environment.

That separation between process placement and socket placement is the mechanism that makes the design interesting. Ambient does not have to put a proxy container beside each application to achieve capture behavior resembling a sidecar. Linux allows a process to create sockets in another network namespace when it has the necessary namespace reference and permissions. Istio uses that capability to move the interception point away from host-level CNI rules.

I find ambient compelling where it can reduce the operational coupling between applications and mesh infrastructure. Istio already adds a distributed system to operate. Removing a per-pod proxy is useful only if the replacement does not introduce a growing collection of exceptions for the cluster's existing network implementation. This change addresses that compatibility problem directly.

Istio CNI extends the primary network

The article distinguishes the primary CNI from the Istio CNI component. A primary CNI implementation establishes the networking through which pods communicate. Istio does not replace it with a required primary implementation of its own. The Istio CNI component extends the existing arrangement and is required for ambient mode.

This matters because the primary CNI can use several mechanisms to move packets. The article identifies overlays, different namespace paths and kernel-level processing among the possible designs. A mesh capture rule that assumes one particular host path can miss traffic or collide with rules installed by another implementation. A nominally shared Kubernetes API does not force every CNI to implement packet delivery identically.

The ambient alpha path redirected application traffic through the host namespace into the node's ztunnel pod namespace. It depended on placing interception rules where the primary CNI was also making routing and policy decisions. The article reports both connectivity conflicts and possible interference with NetworkPolicy enforcement. Supporting each implementation through special handling would make compatibility an ongoing maintenance burden.

The authors also considered eBPF and explain why it would not automatically solve the composition problem. The obstacle was safely combining independently implemented networking programs, not simply choosing a faster packet-processing technology. Without a standardized way to chain arbitrary programs, a change in implementation language or mechanism would preserve the same coordination problem.

NetworkPolicy compatibility is particularly important because working connectivity can conceal a policy interaction. A packet reaching its destination establishes that some delivery path exists. It does not establish that the primary CNI applied the intended restrictions along that path. The article's concern about host-level interception therefore includes security behavior as well as availability. Moving the mesh capture point is intended to let the primary CNI continue enforcing its policy without coordinating interception order with Istio's host rules. That is a stronger architectural objective than making one previously broken route pass a connectivity check.

Capture happens before the packet leaves the pod

The new design puts redirection rules inside the application pod's network namespace. The Istio CNI node agent enters that namespace and configures interception there. It then tells the node-local ztunnel to establish the corresponding listening sockets. Packets encounter the capture rules before relying on a particular host-level path chosen by the primary CNI.

For a new pod, the CNI plugin communicates the event to the Istio CNI node agent. The article says startup waits until redirection has been configured successfully. This early integration is intended to avoid a startup interval in which the application can send traffic before ambient capture exists. It does not require an application init container to establish that ordering.

Existing pods use a different event source. When a running pod becomes part of the ambient mesh, the node agent's Kubernetes watcher detects the change and configures redirection. The common mechanism still operates inside the pod network namespace. New-pod creation and enrollment of a running pod therefore converge on the same capture arrangement even though their lifecycle notifications differ.

The enrollment condition described in the article is a namespace label:

metadata:
  labels:
    istio.io/dataplane-mode: ambient

This fragment identifies the requested data-plane mode. It is not the implementation of capture itself. The agent must still observe enrollment, find the pod namespace and coordinate the listeners. A label is useful because it declares membership, while the node components implement the networking changes needed to make that membership effective.

A namespace descriptor connects the components

The Istio CNI agent communicates with ztunnel over a Unix domain socket. It passes a file descriptor representing the application pod's network namespace. That reference gives ztunnel the context needed to create its listening sockets in the correct namespace. The application process does not have to know that this arrangement exists.

The design article names the listener ports as 15008, 15006 and 15001. Ztunnel creates a dedicated proxy instance and listener set for the enrolled pod. Although these sockets belong to the pod's network namespace, the owning process still runs outside the pod. The distinction lets ambient preserve its external node-level proxy while placing interception at a more compatible point.

Enrollment completes after the in-pod rules and ztunnel listeners exist. The ordering connects membership to actual packet handling. Merely installing redirection without a listener would not provide a working proxy path. Likewise, a listener without capture rules would not make ordinary application connections use the mesh. The two node components coordinate both parts of the arrangement.

I prefer this explanation to treating sidecarless operation as a property of process counts alone. The replacement has to specify who owns the sockets and where packets encounter them. Here the process can remain shared at node scope while the relevant network state is specific to each application pod.

Ztunnel keeps a deliberately narrower job

The 2023 ztunnel architecture article explains the division of responsibility that the new capture model preserves. Ztunnel handles secure workload connectivity and authentication, with layer-four authorization and telemetry. It does not parse application HTTP headers or terminate the workload's HTTP traffic to provide the full layer-seven feature set. Waypoint proxies supply that higher-level processing where required.

This separation is why moving capture does not turn ztunnel into an application-specific Envoy sidecar. Its protocol and implementation remain focused on the smaller set of tasks assigned to the node proxy. The architecture article describes a purpose-built configuration representation carried over xDS transport, containing workload and policy information appropriate to that role.

Ztunnel also acts as a certificate-authority client for the colocated workloads it manages. The relevant security identity belongs to the workload, even though certificate management and transport handling occur in the node component. That model remains separate from the primary CNI's job of delivering packets between pods and nodes.

For traffic between enrolled mesh workloads, the capture arrangement supports encrypted transport while the application remains unaware of the mesh. The January article also retains handling for plaintext traffic arriving from outside the mesh. Those are different cases, so the design should not be summarized as a guarantee that every possible connection becomes mutually authenticated merely because one pod has been enrolled.

Compatibility is the reason for the relocation

The January article reports testing across GKE, AKS and EKS, including their offered CNIs, and with Calico, Cilium and OpenShift. The authors position broad platform support as the main requirement for taking ambient to beta. These are project-reported compatibility results for the new design, not a claim that every future network configuration has already been exercised.

The changes have merged for Istio 1.21 and are intended to be enabled by default for ambient in that release. As of this January announcement, the article is describing the implementation selected for the forthcoming release. It is not announcing ambient's beta graduation. The capture mechanism removes a major compatibility obstacle while the broader readiness work continues.

The architectural result is a clearer relationship between the mesh and the primary CNI. Ambient captures traffic within the pod network namespace and leaves the primary implementation responsible for delivering packets around the cluster. Ztunnel remains a node-level process, with per-pod listeners providing the local interception path. That is the specific operating-system mechanism through which Istio reduces its dependence on host-level routing details.