Getting Started

This guide lets you quickly evaluate Istio’s ambient mode. These steps require you to have a cluster running a supported version of Kubernetes (). You can install Istio ambient mode on any supported Kubernetes platform, but this guide will assume the use of kind for simplicity.

Follow these steps to get started with Istio’s ambient mode:

  1. Download and install
  2. Deploy the sample application
  3. Adding your application to ambient
  4. Secure application access
  5. Control traffic
  6. Uninstall

Download and install

  1. Install kind

  2. Download the latest version of Istio (v1.21.0 or later) with Alpha support for ambient mode.

  3. Deploy a new local kind cluster:

    $ kind create cluster --config=- <<EOF
    kind: Cluster
    apiVersion: kind.x-k8s.io/v1alpha4
    name: ambient
    nodes:
    - role: control-plane
    - role: worker
    - role: worker
    EOF
    
  4. Install the Kubernetes Gateway API CRDs, which don’t come installed by default on most Kubernetes clusters:

    $ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
      { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=7f9f51098f405344a3a7eb13c55895c77919f706" | kubectl apply -f -; }
    
  5. Install Istio with the ambient profile on your Kubernetes cluster, using the version of istioctl downloaded above:

    $ istioctl install --set profile=ambient --skip-confirmation
    

    After running the above command, you’ll get the following output that indicates four components (including ztunnel) have been installed successfully!

    ✔ Istio core installed
    ✔ Istiod installed
    ✔ CNI installed
    ✔ Ztunnel installed
    ✔ Installation complete
    
  6. Verify the installed components using the following command:

    $ kubectl get pods,daemonset -n istio-system
    NAME                                        READY   STATUS    RESTARTS   AGE
    pod/istio-cni-node-btbjf                    1/1     Running   0          2m18s
    pod/istiod-55b74b77bd-xggqf                 1/1     Running   0          2m27s
    pod/ztunnel-5m27h                           1/1     Running   0          2m10s
    
    NAME                            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
    daemonset.apps/istio-cni-node   1         1         1       1            1           kubernetes.io/os=linux   2m18s
    daemonset.apps/ztunnel          1         1         1       1            1           kubernetes.io/os=linux   2m10s
    

Deploy the sample application

You’ll use the sample bookinfo application, which is part of the Istio distribution that you downloaded above. In ambient mode, you deploy applications to your Kubernetes cluster exactly the same way you would without Istio. This means that you can have your applications running in your cluster before you enable ambient mode, and have them join the mesh without needing to restart or reconfigure them.

  1. Start the sample services:

    Zip
    $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@
    
    ZipZip
    $ kubectl apply -f @samples/sleep/sleep.yaml@
    $ kubectl apply -f @samples/sleep/notsleep.yaml@
    

    sleep and notsleep are two simple applications that can serve as curl clients.

  2. Deploy an ingress gateway so you can access the bookinfo app from outside the cluster:

    Create a Kubernetes Gateway and HTTPRoute:

    Zip
    $ sed -e 's/from: Same/from: All/'\
          -e '/^  name: bookinfo-gateway/a\
      namespace: istio-system\
    '     -e '/^  - name: bookinfo-gateway/a\
        namespace: istio-system\
    ' @samples/bookinfo/gateway-api/bookinfo-gateway.yaml@ | kubectl apply -f -
    

    Set the environment variables for the Kubernetes Gateway:

    $ kubectl wait --for=condition=programmed gtw/bookinfo-gateway -n istio-system
    $ export GATEWAY_HOST=bookinfo-gateway-istio.istio-system
    $ export GATEWAY_SERVICE_ACCOUNT=ns/istio-system/sa/bookinfo-gateway-istio
    
  3. Test your bookinfo application. It should work with or without the gateway:

    $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    
    $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    
    $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    

Adding your application to the ambient mesh

  1. You can enable all pods in a given namespace to be part of an ambient mesh by simply labeling the namespace:

    $ kubectl label namespace default istio.io/dataplane-mode=ambient
    namespace/default labeled
    

    Congratulations! You have successfully added all pods in the default namespace to the mesh. Note that you did not have to restart or redeploy anything!

  2. Now, send some test traffic:

    $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    
    $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    
    $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    

You’ll immediately gain mTLS communication and L4 telemetry among the applications in the ambient mesh. If you follow the instructions to install Prometheus and Kiali, you’ll be able to visualize your application in Kiali’s dashboard:

Kiali dashboard
Kiali dashboard

Secure application access

After you have added your application to an ambient mode mesh, you can secure application access using Layer 4 authorization policies. This feature lets you control access to and from a service based on client workload identities, but not at the Layer 7 level, such as HTTP methods like GET and POST.

Layer 4 authorization policy

  1. Explicitly allow the sleep and gateway service accounts to call the productpage service:

    $ kubectl apply -f - <<EOF
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      selector:
        matchLabels:
          app: productpage
      action: ALLOW
      rules:
      - from:
        - source:
            principals:
            - cluster.local/ns/default/sa/sleep
            - cluster.local/$GATEWAY_SERVICE_ACCOUNT
    EOF
    
  2. Confirm the above authorization policy is working:

    $ # this should succeed
    $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    
    $ # this should succeed
    $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    
    $ # this should fail with a connection reset error code 56
    $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    command terminated with exit code 56
    

Layer 7 authorization policy

  1. Using the Kubernetes Gateway API, you can deploy a waypoint proxy for your namespace:

    $ istioctl x waypoint apply --enroll-namespace --wait
    waypoint default/waypoint applied
    namespace default labeled with "istio.io/use-waypoint: waypoint"
    
  2. View the waypoint proxy status; you should see the details of the gateway resource with Programmed status:

    $ kubectl get gtw waypoint -o yaml
    ...
    status:
      conditions:
      - lastTransitionTime: "2024-04-18T14:25:56Z"
        message: Resource programmed, assigned to service(s) waypoint.default.svc.cluster.local:15008
        observedGeneration: 1
        reason: Programmed
        status: "True"
        type: Programmed
    
  3. Update your AuthorizationPolicy to explicitly allow the sleep service to GET the productpage service, but perform no other operations:

    $ kubectl apply -f - <<EOF
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      targetRef:
        kind: Service
        group: ""
        name: productpage
      action: ALLOW
      rules:
      - from:
        - source:
            principals:
            - cluster.local/ns/default/sa/sleep
        to:
        - operation:
            methods: ["GET"]
    EOF
    
  4. Confirm the new waypoint proxy is enforcing the updated authorization policy:

    $ # this should fail with an RBAC error because it is not a GET operation
    $ kubectl exec deploy/sleep -- curl -s "http://productpage:9080/productpage" -X DELETE
    RBAC: access denied
    
    $ # this should fail with an RBAC error because the identity is not allowed
    $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
    RBAC: access denied
    
    $ # this should continue to work
    $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>
    

Control traffic

  1. You can use the same waypoint to control traffic to reviews. Configure traffic routing to send 90% of requests to reviews v1 and 10% to reviews v2:

    ZipZip
    $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-versions.yaml@
    $ kubectl apply -f @samples/bookinfo/gateway-api/route-reviews-90-10.yaml@
    
  2. Confirm that roughly 10% of the traffic from 100 requests goes to reviews-v2:

    $ kubectl exec deploy/sleep -- sh -c "for i in \$(seq 1 100); do curl -s http://productpage:9080/productpage | grep reviews-v.-; done"
    

Uninstall

  1. The label to instruct Istio to automatically include applications in the default namespace to an ambient mesh is not removed by default. If no longer needed, use the following command to remove it:

    $ kubectl label namespace default istio.io/dataplane-mode-
    $ kubectl label namespace default istio.io/use-waypoint-
    
  2. To remove waypoint proxies, installed policies, and uninstall Istio:

    $ istioctl x waypoint delete --all
    $ istioctl uninstall -y --purge
    $ kubectl delete namespace istio-system
    
  3. To delete the Bookinfo sample application and its configuration, see Bookinfo cleanup.

  4. To remove the sleep and notsleep applications:

    ZipZip
    $ kubectl delete -f @samples/sleep/sleep.yaml@
    $ kubectl delete -f @samples/sleep/notsleep.yaml@
    
  5. If you installed the Gateway API CRDs, remove them:

    $ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=7f9f51098f405344a3a7eb13c55895c77919f706" | kubectl delete -f -
    
Was this information useful?
Do you have any suggestions for improvement?

Thanks for your feedback!