Configure waypoint proxies

Configure waypoint proxies

A waypoint proxy is an optional deployment of an Envoy-based proxy that adds Layer 7 (L7) processing to a defined set of workloads.

Waypoint proxies are installed, upgraded and scaled independently from applications; an application owner should be unaware of their existence. Unlike in a sidecar-based service mesh architecture where an instance of the Envoy proxy runs alongside each workload, the number of required proxies for L7 processing is substantially reduced in ambient mesh.

A waypoint, or set of waypoints, can be shared between applications with a similar security boundary. This might be all the instances of a particular workload, or all the workloads in a namespace.

Layer 7 policies are enforced by the waypoint that is associated with the target destination. Because of that, the waypoint acts as a gateway for resources in a cluster, such as a namespace, service or pod.

Is a waypoint required?

The layered approach of ambient mesh allows users to adopt Istio in a more incremental fashion so that you can smoothly transition from having no mesh, to the secure overlay layer provided by ztunnel, to full L7 processing.

The ztunnel is scoped to only process traffic at Layer 4 (L4), so that it can safely operate as a shared component. However, if your app requires any of the following L7 policies and L7 routing capabilities, you must deploy a waypoint proxy:

  • Traffic management: HTTP routing, HTTP load balancing, circuit breaking, rate limiting, fault injection, retries, and timeouts
  • Security: Authorization policies based on L7 primitives, such as request types or HTTP headers
  • Observability: HTTP metrics, access logging, tracing

After you deploy a waypoint proxy, traffic is automatically redirected from the ztunnel to the waypoint proxy so that L7 policies can be applied.

Deploy waypoints

Waypoint proxies are deployed using the Kubernetes Gateway API. To make it easier to create a waypoint configuration, and apply it to your resources, you can use istioctl waypoint subcommands.

⚠️
After the waypoint is deployed, the entire namespace (or whichever services or pods you choose) must be enrolled to use it.

Confirm workloads in the mesh

Before you deploy a waypoint proxy for a specific namespace, confirm the namespace is labeled with istio.io/dataplane-mode: ambient:

$ kubectl get ns -L istio.io/dataplane-mode

Example output:

NAME              STATUS   AGE   DATAPLANE-MODE
istio-system      Active   24h
default           Active   24h   ambient

Generate a waypoint config

The istioctl command can generate configuration for a waypoint proxy for all the services in the default namespace. You can preview the output using waypoint generate, or apply it directly using waypoint apply.

$ istioctl waypoint generate --for service -n default
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  labels:
    istio.io/waypoint-for: service
  name: waypoint
  namespace: default
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE

Deploy the waypoint proxy

Use the istioctl waypoint apply command to create a waypoint proxy for the default namespace. Notice that the command uses the --enroll-namespace option. This option automatically labels the namespace with the name of the waypoint proxy so that your workloads can start using it. If you want to manually apply the label, remove the --enroll-namespace option and check out use the waypoint proxy to learn how to apply the label yourself.

$ istioctl waypoint apply -n default --enroll-namespace
waypoint default/waypoint applied

Congratulations! You successfully deployed a waypoint proxy for the apps in the default namespace. The Istio control plane automatically monitors the Gateway resource, and deploys and manages the waypoint proxy deployment and service for you.

Waypoint traffic types

By default, a waypoint will handle traffic only for the services in its namespaces. This was a deliberate choice as directing traffic at the pod level is rare and often used for internal purposes such as Prometheus scraping. The extra overhead of L7 processing may not be desired in these cases.

It is possible for the waypoint to handle all types of traffic, including traffic sent directly to workloads (pods or VMs) in the cluster, or no traffic at all. The types of traffic that are redirected to the waypoint proxy are determined by the istio.io/waypoint-for label on the Gateway resource.

Use the --for option in the istioctl waypoint apply command to configure the value of the waypoint-for label.

waypoint-for value Destination type
service Kubernetes services
workload Pod IPs or VM IPs
all Both service and workload traffic
none No traffic (useful for testing)

For example, to apply a waypoint to all services and workloads in the default namespace:

$ istioctl waypoint apply -n default --for all
Waypoint selection occurs based on the destination type, service or workload, to which traffic was originally addressed. If traffic is addressed to a service which does not have a waypoint, a waypoint will not be transited, even if the workload it reaches does have an attached waypoint.

Enroll namespaces or services into waypoints

When a waypoint proxy is deployed, it is not used by any resources until you explicitly configure those resources to use it. To enable a namespace, service, or pod to use a waypoint, add the istio.io/use-waypoint label with the waypoint name.

Configure a namespace to use a waypoint

Most users want to apply a waypoint to an entire namespace, and we recommend you start with this approach.

If you use istioctl to deploy your namespace waypoint, you can use the --enroll-namespace parameter to automatically label a namespace:

$ istioctl waypoint apply -n default --enroll-namespace

Alternatively, you can add the label to the namespace directly:

$ kubectl label ns default istio.io/use-waypoint=waypoint

After a namespace is enrolled to use a waypoint, any requests from any pods in the ambient mesh to any service that runs in that namespace, is routed through the waypoint proxy for L7 processing and policy enforcement.

Want to have more granular control over the resources that use the waypoint? With ambient mesh, you can add a waypoint proxy to a particular service or pod. This can be useful if you only need L7 features for some services in a namespace, if you only want an extension like a WasmPlugin to apply to a specific service, or if you are calling a Kubernetes headless service by its pod IP address.

If the istio.io/use-waypoint label exists on both a namespace and a service, the service waypoint takes precedence over the namespace waypoint as long as the service waypoint can handle service or all traffic. Similarly, a label on a pod will take precedence over a namespace label.

Configure a service to use a specific waypoint

Using the services from the sample application, we can deploy a waypoint called reviews-svc-waypoint for only the reviews service:

$ istioctl waypoint apply -n default --name reviews-svc-waypoint

Label the reviews service to use the reviews-svc-waypoint waypoint:

$ kubectl label service reviews istio.io/use-waypoint=reviews-svc-waypoint

Any requests from pods in the mesh to the reviews service will now be routed through the reviews-svc-waypoint waypoint.

Configure a pod to use a specific waypoint

Keep in mind that the default destination type for waypoints are services. Because we want to target a specific pod, we need to use the istio.io/waypoint-for: workload label on the waypoint proxy. You can automatically generate this label by using the --for workload option when applying your waypoint.

Deploy a waypoint called reviews-v2-pod-waypoint for the reviews-v2 pod.

$ istioctl waypoint apply -n default --name reviews-v2-pod-waypoint --for workload

Label the reviews-v2 pod to use the reviews-v2-pod-waypoint waypoint:

$ kubectl label pod -l version=v2,app=reviews istio.io/use-waypoint=reviews-v2-pod-waypoint

Any requests from pods in the ambient mesh to the reviews-v2 pod IP will now be routed through the reviews-v2-pod-waypoint waypoint for L7 processing and policy enforcement.

The original destination type of the traffic is used to determine if a service or workload waypoint will be used. By using the original destination type the ambient mesh avoids having traffic transit waypoint twice, even if both service and workload have attached waypoints. For instance, traffic which is addressed to a service, even though ultimately resolved to a pod IP, is always treated by the ambient mesh as to-service and would use a service-attached waypoint.

Use waypoints from other namespaces

By default, a waypoint proxy can be used by resources within the same namespace. However, it is possible to use waypoints from other namespaces.

Configure a waypoint for cross-namespace use

In order to enable cross-namespace use of a waypoint, the Gateway must be configured to allow routes from other namespaces.

The keyword All can be specified as the value for allowedRoutes.namespaces.from in order to allow routes from any namespace.

The following Gateway resource allows routes from a namespace called cross-namespace-waypoint-consumer to use the egress-gateway.

kind: Gateway
metadata:
  name: egress-gateway
  namespace: common-infrastructure
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            kubernetes.io/metadata.name: cross-namespace-waypoint-consumer

Configure resources to use a cross-namespace waypoint proxy

By default, the Istio control plane looks for a waypoint in the same namespace as the resource that is configured to use a waypoint. To do that, the control plane looks extracts the waypoint proxy name from the istio.io/use-waypoint label that is applied to the resource.

To instruct the control plane to look for a waypoint in a different namespace, you must apply the istio.io/use-waypoint and istio.io/use-waypoint-namespace labels to your resource. Together, these two labels specify the name and namespace of your waypoint.

For example, to configure a ServiceEntry named istio-site to use a waypoint named egress-gateway in the namespace named common-infrastructure, you could use the following commands:

$ kubectl label serviceentries.networking.istio.io istio-site istio.io/use-waypoint=egress-gateway
$ kubectl label serviceentries.networking.istio.io istio-site istio.io/use-waypoint-namespace=common-infrastructure

Attach policies and routes

A route or policy can be scoped to apply to all traffic traversing a waypoint proxy, or only specific services.

Attach to the entire waypoint proxy

To attach a route or policy to a waypoint so that it is applied to all traffic that passes through the waypoint, use kind: Gateway and the name of the waypoint in the spec.parentRefs (route) or spec.targetRefs (policy) field. The following AuthorizationPolicy applies to a waypoint proxy named default in the default namespace.

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: view-only
  namespace: default
spec:
  targetRefs:
  - kind: Gateway
    group: gateway.networking.k8s.io
    name: default
  action: ALLOW
  rules:
  - from:
    - source:
        namespaces: ["default", "istio-system"]
    to:
    - operation:
        methods: ["GET"]

Attach to a specific service

You can also attach a route to one or more specific services within the waypoint. Set Service as the parentRefs or targetRefs value, as appropriate.

To apply the reviews HTTPRoute to the reviews service in the default namespace:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
  namespace: default
spec:
  parentRefs:
  - group: ""
    kind: Service
    name: reviews
    port: 9080
  rules:
  - backendRefs:
    - name: reviews-v1
      port: 9080
      weight: 90
    - name: reviews-v2
      port: 9080
      weight: 10

Remove waypoints

To remove the waypoint layer from a namespace, delete the Gateway resources and remove the enrollment label. The folling commands removes all waypoint proxies in the default namespace.

$ istioctl waypoint delete --all -n default
$ kubectl label ns default istio.io/use-waypoint-