Skip to content

Traffic splitting

Page as Markdown

    

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

  1. Follow the quickstart to install ambient mesh and deploy the Bookinfo sample application.

  2. If you don’t already have a waypoint deployed for the default namespace, 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).

  1. Verify that all three versions are running.

    kubectl get pods

    Example 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          42s
    

    The reviews service selects all three pods by the app: reviews label. The version labels exist but are not used by the service, so traffic is load balanced across all versions.

  2. Create version-specific services that target each version of the reviews pods.

    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
  3. Create an HTTPRoute that routes all traffic from the reviews service to reviews-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
  4. 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.

  1. Update the HTTPRoute to split traffic 50/50 between reviews-v1 and reviews-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
  2. Refresh the Bookinfo product page several times. Approximately 50% of requests show no stars (v1) and 50% show red stars (v3).

  3. 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.

  1. Apply an HTTPRoute that routes requests with end-user: blackstar to reviews-v2 and all other traffic to reviews-v1. When you log in to Bookinfo, the application sets the end-user header 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
  2. Open the Bookinfo product page without logging in. The reviews section shows no stars (v1).

  3. 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