> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Install Istio Ambient Mode via CLI

> Guide to installing Istio Ambient mode with istioctl, labeling namespaces, verifying ztunnel L4 interception, and enabling waypoint proxies for Layer 7 using Kubernetes Gateway API

This guide shows how to install Istio in Ambient mode using the `istioctl` CLI. Ambient mode differs from the classic sidecar approach primarily in the profile you install and how you label namespaces. The steps below walk through download, install, namespace labeling, smoke tests, enabling Layer 7 with waypoint proxies, and optional cleanup. Commands and sample outputs are included for quick verification.

## Prerequisites

* A Kubernetes cluster (kubectl configured).
* Permissions to create CRDs, namespaces, and cluster-level resources.
* A supported Istio release (examples use 1.26.3).

## 1) Download Istio and add istioctl to PATH

Download a specific Istio release and add `istioctl` to your PATH:

```bash theme={null}
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.26.3 sh -
cd istio-1.26.3
export PATH=$PWD/bin:$PATH
```

Sample installer output (trimmed):

```bash theme={null}
# ... download progress ...
Istio 1.26.3 download complete!

To configure the istioctl client tool for your workstation,
add the /root/istio-1.26.3/bin directory to your environment path variable with:
    export PATH="$PATH:/root/istio-1.26.3/bin"

Begin the Istio pre-installation check by running:
    istioctl x precheck
```

Verify the client version (the cluster will not have Istio pods yet):

```bash theme={null}
istioctl version
```

Example output:

```bash theme={null}
Istio is not present in the cluster: no running Istio pods in namespace "istio-system"
client version: 1.26.3
```

## 2) Install Istio with the ambient profile

Install Istio using the Ambient profile. This configures control-plane components and the Ambient dataplane components (ztunnel + istio-cni):

```bash theme={null}
istioctl install --set profile=ambient -y
```

The installer prints progress and the resources it creates. After the installation finishes, confirm the core control-plane and dataplane components are running:

```bash theme={null}
kubectl get pods -n istio-system
```

Example output:

```bash theme={null}
NAME                       READY   STATUS    RESTARTS   AGE
istio-cni-node-rc84w       1/1     Running   0          3m
istiod-6b854648cc-z54lj    1/1     Running   0          3m
ztunnel-kbc9c              1/1     Running   0          3m
```

Notes:

* Ambient mode uses `ztunnel` to perform transparent L4 interception, while `istio-cni` (DaemonSet) handles per-node networking/CNI tasks.
* On a multi-node cluster, daemonsets (istio-cni and ztunnel) will typically show one pod per node.

You can explicitly list daemonsets:

```bash theme={null}
kubectl get ds -n istio-system
```

## 3) Label the namespace for Ambient dataplane mode

Ambient mode does not rely on `istio-injection=enabled`. Instead, label the namespace with `istio.io/dataplane-mode=ambient`.

Check current namespaces and labels:

```bash theme={null}
kubectl get ns --show-labels
```

Example output before labeling:

```bash theme={null}
NAME               STATUS   AGE    LABELS
default            Active   3m7s   kubernetes.io/metadata.name=default
istio-system       Active   73s    kubernetes.io/metadata.name=istio-system
kube-system        Active   3m7s   kubernetes.io/metadata.name=kube-system
```

Istio analyzer may report suggestions oriented to sidecar injection. For example:

```bash theme={null}
istioctl analyze -n default
```

Sample analyzer info:

```bash theme={null}
Info [IST0102] (Namespace default) The namespace is not enabled for Istio injection. Run 'kubectl label namespace default istio-injection=enabled' to enable it, or 'kubectl label namespace default istio-injection=disabled' to explicitly mark it as not needing injection.
```

For Ambient mode, set the dataplane label:

```bash theme={null}
kubectl label namespace default istio.io/dataplane-mode=ambient
```

Verify the label:

```bash theme={null}
kubectl get ns --show-labels
```

Example output after labeling:

```bash theme={null}
NAME        STATUS   AGE     LABELS
default     Active   4m28s   istio.io/dataplane-mode=ambient,kubernetes.io/metadata.name=default
istio-system Active  2m34s   kubernetes.io/metadata.name=istio-system
```

<Callout icon="lightbulb" color="#1CB2FE">
  Ambient mode uses `istio.io/dataplane-mode=ambient` instead of `istio-injection=enabled`. istioctl analyze may still show messages for sidecar-style injection even after you label a namespace for ambient mode.
</Callout>

## 4) Run a test pod and verify L4 interception

Create a simple test pod (NGINX) in the labeled namespace and check its state:

```bash theme={null}
kubectl run test --image=nginx
kubectl get pods
```

Expected pod state:

```bash theme={null}
NAME   READY   STATUS    RESTARTS   AGE
test   1/1     Running   0          30s
```

Notice: Unlike sidecar mode, the pod will not show a second container (no 2/2). Ambient mode relies on `ztunnel` for transparent L4 interception rather than injecting a sidecar into every workload.

Confirm Istio system pods:

```bash theme={null}
kubectl get pods -n istio-system
```

Tail the ztunnel logs to observe intercepted L4 traffic. First list the ztunnel pod:

```bash theme={null}
kubectl get pods -n istio-system
```

Then stream logs (replace the pod name with your actual pod name):

```bash theme={null}
kubectl logs -n istio-system -f ztunnel-kbc9c
```

You should see lines indicating listeners and xDS updates:

```bash theme={null}
2025-08-30T19:40:45.581334Z info proxy::outbound listener established address=[::]:15001 component="outbound" transparent=true
2025-08-30T19:40:50.354853Z info xds::client:xds{id=1} received response type_url="type.googleapis.com/istio.workload.Address" size=1 removes=0
```

From another terminal, make an outbound request from the test pod:

```bash theme={null}
kubectl exec test -- curl --head www.google.com
```

Sample HTTP response:

```bash theme={null}
HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
Date: Sat, 30 Aug 2025 19:41:57 GMT
Server: gws
...
```

And the ztunnel access log should show the intercepted outbound connection:

```bash theme={null}
2025-08-30T19:41:57.039950Z info access connection complete src.addr=10.50.0.7:46996 src.workload="test" src.namespace="default" dst.addr=74.125.126.104:80 direction="outbound" bytes_sent=79 bytes_recv=1028 duration="63ms"
```

This confirms ztunnel is intercepting and routing L4 traffic for workloads in the namespace labeled with `istio.io/dataplane-mode=ambient`.

## 5) CRDs and waypoint proxy for Layer 7 (L7) functionality

Ambient mode provides transparent L4 interception out of the box. To enable Layer 7 capabilities like routing, fault injection, and traffic mirroring, Istio introduces the waypoint proxy and integrates with the Kubernetes Gateway API (e.g., HTTPRoute). These L7 features require additional CRDs beyond the core Istio CRDs.

List CRDs installed by Istio:

```bash theme={null}
kubectl get crd
```

Common Istio CRDs include:

| CRD (examples)                            |
| ----------------------------------------- |
| `authorizationpolicies.security.istio.io` |
| `destinationrules.networking.istio.io`    |
| `envoyfilters.networking.istio.io`        |
| `gateways.networking.istio.io`            |
| `virtualservices.networking.istio.io`     |
| `wasmplugins.extensions.istio.io`         |
| `workloadentries.networking.istio.io`     |
| `workloadgroups.networking.istio.io`      |

After enabling waypoint and Gateway API resources you may also see:

| Gateway API CRDs                            |
| ------------------------------------------- |
| `gatewayclasses.gateway.networking.k8s.io`  |
| `httproutes.gateway.networking.k8s.io`      |
| `referencegrants.gateway.networking.k8s.io` |
| `grpcroutes.gateway.networking.k8s.io`      |

To enable a waypoint proxy for a namespace (example uses `default`):

```bash theme={null}
istioctl waypoint apply -n default
```

Sample output:

```bash theme={null}
✅ waypoint default/waypoint applied
```

After applying, check for the waypoint Deployment and pods:

```bash theme={null}
kubectl get pods -n default
```

Example:

```bash theme={null}
NAME                             READY   STATUS    RESTARTS   AGE
test                             1/1     Running   0          2m
waypoint-7cb5d4bd6-crnmp         1/1     Running   0          7s
```

The waypoint proxy is responsible for Layer 7 capabilities in Ambient mode and integrates with Kubernetes Gateway API resources (HTTPRoute, GatewayClass, etc.). These APIs are separate from classic Istio VirtualService resources and require the corresponding CRDs.

<Callout icon="lightbulb" color="#1CB2FE">
  Waypoint proxies enable Layer 7 features in Ambient mode using the Kubernetes Gateway API (HTTPRoute, GatewayClass, etc.). These APIs and CRDs are separate from classic Istio VirtualService resources.
</Callout>

## 6) Delete the waypoint proxy (optional)

To remove the waypoint proxy in the namespace:

```bash theme={null}
istioctl waypoint delete --all -n default
```

Sample output:

```bash theme={null}
waypoint default/waypoint deleted
```

The waypoint Pod/Deployment may take a short time to terminate.

## 7) What matters for the ICA exam and practical checks

Key points to remember and verify:

* Install Istio Ambient mode:
  * `istioctl install --set profile=ambient -y`
  * Label namespaces with `istio.io/dataplane-mode=ambient`
* Confirm L4 interception by inspecting `ztunnel` logs and verifying outbound connections from application pods.
* Waypoint proxy + Kubernetes Gateway API provide L7 capabilities in Ambient mode; they require additional CRDs (HTTPRoute, GatewayClass, etc.).
* Deep configuration of HTTPRoute, VirtualService, or EnvoyFilter for Ambient L7 is generally outside the core ICA exam scope.

Comparison (Ambient vs Sidecar):

| Concern             | Ambient mode                      | Sidecar mode                           |
| ------------------- | --------------------------------- | -------------------------------------- |
| Injection label     | `istio.io/dataplane-mode=ambient` | `istio-injection=enabled`              |
| L4 interception     | ztunnel (transparent)             | iptables + sidecar proxy               |
| Workload containers | No sidecar per pod                | Sidecar container injected (2/2)       |
| L7 features         | Waypoint proxy + Gateway API      | VirtualService / Gateway / EnvoyFilter |

References

* Istio Waypoint docs: [https://istio.io/latest/docs/tasks/traffic-management/waypoint/](https://istio.io/latest/docs/tasks/traffic-management/waypoint/)
* Kubernetes Gateway API: [https://gateway-api.sigs.k8s.io/](https://gateway-api.sigs.k8s.io/)
* Istio VirtualService: [https://istio.io/latest/docs/reference/config/networking/virtual-service/](https://istio.io/latest/docs/reference/config/networking/virtual-service/)
* Istio EnvoyFilter: [https://istio.io/latest/docs/reference/config/networking/envoy-filter/](https://istio.io/latest/docs/reference/config/networking/envoy-filter/)

That completes the Ambient mode installation walkthrough and a basic demonstration of L4 interception with optional Waypoint L7 setup.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/istio-certified-associate/module/65ee174b-536e-4657-9b6f-85c90c7612da/lesson/105379ce-f1aa-4d80-ab41-b3bf398a80e1" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/istio-certified-associate/module/65ee174b-536e-4657-9b6f-85c90c7612da/lesson/dcd771d9-ecff-4b53-bbbc-a98e43ab95b9" />
</CardGroup>
