For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Waypoint
Learn how L7 load balancing, outlier detection, and failover work for waypoint proxies.
When a waypoint proxy is in the path, L7 load balancing applies. Waypoints use the HBONE protocol to talk directly to the backend or to the next hop. On that leg of the path, traffic is not captured by the ztunnel, so Envoy performs L7 load balancing.
Traffic distribution still applies, such as on the waypoint’s service and on the backend service. When you need finer control than traffic distribution provides, you can apply an Istio DestinationRule, such as for HTTP-based outlier detection or a custom failover order. The rule is enforced at the waypoint and overrides the traffic distribution setting for that host.
Note
Solo Enterprise for agentgateway behaves the same as the Istio waypoint when used as a waypoint proxy.
Cluster scenarios
The following diagrams give examples of how the waypoint handles load balancing, outlier detection, and failover in single-cluster and multicluster setups.
Single-cluster scenario
- The request routes from the client app to the backend app.
- Both the client and backend services are enrolled in the ambient mesh and run in the same cluster.
- The backend app has L7 policies defined that are enforced by a waypoint proxy.
- The backend service has multiple replicas distributed across different zones or regions within the cluster.
- Optionally, the
spec.trafficDistributionornetworking.istio.io/traffic-distributionsetting is configured on the backend service to control locality-based load balancing.
graph LR
Client[Client pod] -->|1. L4| Ztunnel1[Client<br/>ztunnel]
Ztunnel1 -->|2. HBONE| Waypoint[Waypoint<br/>L7 proxy]
Waypoint -->|3. Load balancing| Backend1[Backend pod<br/>✓ Healthy]
Waypoint -->|3. Load balancing| Backend2[Backend pod<br/>✓ Healthy]
Waypoint -.->|"Outlier detection: ejected"| Backend3[Backend pod<br/>✗ Unhealthy]
style Waypoint fill:#2068F3,color:#fff
Multicluster scenario
- The request routes from the client app to the backend app.
- Both the client and backend services are enrolled in the ambient mesh.
- The backend app has L7 policies defined that are enforced by a waypoint proxy.
- The backend app is exposed as a global service with the
solo.io/service-scope=globalannotation. - The
networking.istio.io/traffic-distributionannotation is set on the global service. Note that other service-scope annotations likesolo.io/service-scope=global-only,solo.io/service-scope=segment,solo.io/service-scope=cluster, orsolo.io/service-takeover: true, behave in the same way. Only the number of endpoints that can be addressed differs, such as only the endpoints within the same cluster or segment.
graph LR
subgraph Cluster1["Cluster 1"]
Client[Client pod]
Ztunnel1[Client<br/>ztunnel]
Waypoint[Waypoint]
Backend1[Backend pod<br/>✓ Healthy]
Client -->|1. L4| Ztunnel1
Ztunnel1 -->|2. HBONE| Waypoint
Waypoint -->|"3. Local endpoint<br/>(global service)"| Backend1
end
subgraph Cluster2["Cluster 2"]
Backend2[Backend pod<br/>✓ Healthy]
Backend3[Backend pod<br/>✗ Unhealthy]
end
Waypoint -->|"3. Cross-cluster<br/>(global service)"| Backend2
Waypoint -.->|"Outlier detection: ejected"| Backend3
style Waypoint fill:#2068F3,color:#fff
Locality determination
Traffic flows through two paths when using waypoints, and locality is determined separately in each path.
Client (ztunnel) → waypoint:
- Endpoints are determined by comparing the client’s ztunnel locality with the locality labels on the waypoint.
- After locality is determined, the traffic distribution mode on the waypoint applies. For example, the default
PreferClosemode prefers a waypoint that is in the same network, region, and zone as the client, and falls back to a waypoint in a farther locality when no closer waypoint is available. - This behavior follows the L4 ztunnel failover behavior.
Waypoint → backend:
- Endpoints are determined by comparing the waypoint’s locality with the locality of the backend.
- After locality is determined, the traffic distribution mode on the backend applies. For example, if the backend has the
Anymode, the waypoint round robins between the backend endpoints. - This behavior follows the L7 Envoy failover behavior.
Load balancing
Client (ztunnel) → waypoint:
Traffic distribution is enforced via the traffic distribution setting on the service that exposes the waypoint Gateway. The following precedence order applies:
- Service
spec.trafficDistribution(highest precedence, Kubernetes-native, supportsPreferCloseonly) - Service
networking.istio.io/traffic-distributionannotation (Istio-extended, supports all modes) - Namespace
networking.istio.io/traffic-distributionannotation (Istio-extended, supports all modes) Any(lowest precedence). In this case, no locality preference applies, and the client ztunnel selects uniformly across every waypoint endpoint.
Defaults: When you create a waypoint Gateway, Istio generates the service for the waypoint and annotates that service with networking.istio.io/traffic-distribution: PreferClose. The waypoint therefore defaults to PreferClose.
Warning
The PreferClose default for a waypoint comes from the generated annotation, not from the lowest level of the precedence order. To set your own annotations on the generated waypoint service, use the spec.infrastructure.annotations field on the waypoint Gateway. An annotation that you set there replaces the generated one. If you replace PreferClose with Any, the waypoint loses every locality preference, including the preference for waypoint endpoints in the client’s own network.
Waypoint → backend:
Traffic distribution is enforced via the traffic distribution setting on the global service. The following precedence order applies:
- Service
spec.trafficDistribution(highest precedence, Kubernetes-native, supportsPreferCloseonly) - Service
networking.istio.io/traffic-distributionannotation (Istio-extended, supports all modes) - ServiceEntry
networking.istio.io/traffic-distributionannotation (Istio-extended, supports all modes). Use this when you use a ServiceEntry. - Namespace
networking.istio.io/traffic-distributionannotation (Istio-extended, supports all modes) UNSPECIFIED_MODE(default, lowest precedence). In this case, the behavior of thePreferNetworkmode is used.
Defaults: If you do not explicitly set traffic distribution modes, PreferClose is used for the waypoint, because Istio annotates the generated waypoint service with that mode. For a global service, PreferNetwork is used for the backend, because multicluster peering annotates the generated ServiceEntry with that mode. A backend service that is not exposed across clusters uses Any.
To review the available traffic distribution modes and how each mode prioritizes endpoints, see Traffic distribution modes and endpoint priority. Note that these modes apply only if no DestinationRule is in place.
Waypoint selection across peered clusters
When you peer clusters, the waypoint instances that share a name and namespace merge into a single waypoint service. Each instance becomes an endpoint of that merged service, and the client ztunnel selects between those endpoints.
An instance that runs in a peered cluster on a remote network is a selectable endpoint of the merged waypoint service. Earlier versions of Istio suppressed those instances. As a result, a service whose same-network waypoints had no endpoints became unreachable, and the client ztunnel logged unknown waypoint.
The traffic distribution of the merged waypoint service is derived as follows:
- If the local cluster runs an instance of the waypoint, the merged service inherits the traffic distribution of the local waypoint service. For a waypoint that keeps the generated annotation, that mode is
PreferClose. - If the local cluster runs no instance of the waypoint, the merged service takes the mode that the peered clusters agree on. If those clusters disagree,
PreferNetworkapplies.
Both PreferClose and PreferNetwork place same-network endpoints at the highest priority. Steady-state traffic therefore stays on a waypoint in the client’s own network. A waypoint on a remote network is selected only when no same-network waypoint endpoint is available.
Warning
Waypoint selection does not consider whether the selected cluster hosts the destination service. A cluster that runs the waypoint but does not host the destination has no configuration for that destination. Requests that select that waypoint fail. Run the destination service in every cluster that runs the waypoint, or give the waypoint in those clusters a different name.
L7 load-based spillover
When traffic distribution creates priority levels for endpoints, Envoy uses locality weighted load balancing to distribute requests across those priorities. Under high load, Envoy might send some traffic to lower-priority endpoints (farther localities) even when higher-priority endpoints (closer localities) are still healthy.
Envoy uses an overprovisioning factor (default 1.4) to determine when to spill over traffic. A priority level is not considered unhealthy until the percentage of healthy endpoints multiplied by the overprovisioning factor drops below 100. With the default factor, a locality is not considered unhealthy until healthy endpoints drop below approximately 72% (100 / 1.4). When endpoints in a preferred locality approach their capacity under heavy load but are still technically healthy, Envoy begins sending some requests to the next priority level to prevent overload.
This spillover behavior is capacity-based, not failure-based. It is distinct from traditional failover, which occurs when endpoints become unavailable or are ejected due to outlier detection. Spillover is a load-balancing mechanism to prevent hot spots and distribute load more evenly across available capacity.
Outlier detection and failover
The traffic distribution settings that are previously described are the recommended method for detecting and handling unhealthy endpoints.
If these settings cannot meet your requirements, you can define an Istio DestinationRule with outlier detection settings in the spec.trafficPolicy.outlierDetection section. For more information, see the Istio reference for outlierDetection.
The DestinationRule is applied at the waypoint and targets the backend service hostname. In a multicluster setup, use the global service hostname (such as productpage.bookinfo.mesh.internal). In a single-cluster setup, use the standard Kubernetes service hostname (such as productpage.bookinfo.svc.cluster.local or productpage). If multiple services are served by the waypoint, you can specify the hostname of each service in the DestinationRule to set different behavior for each service.
Note that you cannot define a DestinationRule on the request path from the client to the waypoint. However, the logic in DestinationRule that you create for the backend hosts also applies to the path from the client to the waypoint.
For example configurations, see DestinationRule examples.