Traffic splitting
Split traffic by percentage across service versions in ambient mesh using HTTPRoutes, enabling A/B tests and canary rollouts.
HTTPRoutes let you distribute traffic across service versions by weight. In this guide, you route the Bookinfo reviews service to a single version, split traffic across versions to simulate a progressive rollout, and use header-based matching to route a specific user to a canary version.
Note
Traffic splitting is supported at the edge of a cluster using a gateway, or when a workload is enrolled in the waypoint layer. Learn about the different configurations required in each case.
Before you begin
-
Follow the quickstart to install ambient mesh and deploy the Bookinfo sample application.
-
If you don’t already have a waypoint deployed for the
defaultnamespace, deploy one.istioctl waypoint apply --enroll-namespace --wait
Route to a single version
The Bookinfo sample application includes three versions of the reviews microservice. Because Kubernetes load balances across all three pods by default, each page refresh shows a different version: no stars (v1), black stars (v2), or red stars (v3).
-
Verify that all three versions are running.
kubectl get podsExample output:
NAME READY STATUS RESTARTS AGE details-v1-cf74bb974-nw94k 1/1 Running 0 42s productpage-v1-87d54dd59-wl7qf 1/1 Running 0 42s ratings-v1-7c4bbf97db-rwkw5 1/1 Running 0 42s reviews-v1-5fd6d4f8f8-66j45 1/1 Running 0 42s reviews-v2-6f9b55c5db-6ts96 1/1 Running 0 42s reviews-v3-7d99fd7978-dm6mx 1/1 Running 0 42sThe
reviewsservice selects all three pods by theapp: reviewslabel. Theversionlabels exist but are not used by the service, so traffic is load balanced across all versions. -
Create version-specific services that target each version of the
reviewspods.kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: reviews-v1 spec: ports: - port: 9080 name: http selector: app: reviews version: v1 --- apiVersion: v1 kind: Service metadata: name: reviews-v2 spec: ports: - port: 9080 name: http selector: app: reviews version: v2 --- apiVersion: v1 kind: Service metadata: name: reviews-v3 spec: ports: - port: 9080 name: http selector: app: reviews version: v3 EOF -
Create an HTTPRoute that routes all traffic from the
reviewsservice toreviews-v1.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: reviews spec: parentRefs: - group: "" kind: Service name: reviews port: 9080 rules: - backendRefs: - name: reviews-v1 port: 9080 EOF -
Refresh the Bookinfo product page. Every request now goes to
reviews-v1, which shows no star ratings.
Split traffic across versions
An HTTPRoute can reference more than one backend, letting you split traffic by weight across versions. This is the basis of a progressive rollout: start by sending a small percentage to the new version, validate behavior, then gradually increase the weight until you cut over completely.
-
Update the HTTPRoute to split traffic 50/50 between
reviews-v1andreviews-v3.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: reviews spec: parentRefs: - group: "" kind: Service name: reviews port: 9080 rules: - backendRefs: - name: reviews-v1 port: 9080 weight: 50 - name: reviews-v3 port: 9080 weight: 50 EOF -
Refresh the Bookinfo product page several times. Approximately 50% of requests show no stars (v1) and 50% show red stars (v3).
-
Once you are satisfied with the behavior of
reviews-v3, complete the rollout by shifting 100% of traffic to it.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: reviews spec: parentRefs: - group: "" kind: Service name: reviews port: 9080 rules: - backendRefs: - name: reviews-v3 port: 9080 weight: 100 EOF
Canary deployments
A more specific match takes precedence over a more general one. Use this rule to route a specific group of users to a canary version while all other traffic goes to the stable version.
-
Apply an HTTPRoute that routes requests with
end-user: blackstartoreviews-v2and all other traffic toreviews-v1. When you log in to Bookinfo, the application sets theend-userheader to your username.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: reviews spec: parentRefs: - group: "" kind: Service name: reviews port: 9080 rules: - backendRefs: - name: reviews-v2 port: 9080 matches: - headers: - name: end-user value: blackstar - backendRefs: - name: reviews-v1 port: 9080 EOF -
Open the Bookinfo product page without logging in. The reviews section shows no stars (v1).
-
Log in with username
blackstar(any password). The reviews section now shows black stars (v2), confirming that header-based routing is applied only to that user.
Cleanup
Delete the resources created in this guide.
kubectl delete httproute reviews
kubectl delete svc reviews-v1 reviews-v2 reviews-v3