Skip to content

HTTP traffic splitting

Danger

This page has not been updated for v1alpha2 yet.

The HTTPRoute resource allows you to specify weights to shift traffic between different backends. This is useful for splitting traffic during rollouts, canarying changes, or for emergencies. The HTTPRoute spec.rules.forwardTo accepts a list of backends that a route rule will send traffic to. The relative weights of these backends define the split of traffic between them. The following YAML snippet shows how two Services are listed as backends for a single route rule. This route rule will split traffic 90% to foo-v1 and 10% to foo-v2.

Traffic splitting

apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: simple-split
spec:
  rules:
  - forwardTo:
    - serviceName: foo-v1
      port: 8080
      weight: 90
    - serviceName: foo-v2
      port: 8080
      weight: 10  

weight indicates a proportional split of traffic (rather than percentage) and so the sum of all the weights within a single route rule is the denominator for all of the backends. weight is an optional parameter and if not specified, defaults to 1. If only a single backend is specified for a route rule it implicitly recieves 100% of the traffic, no matter what (if any) weight is specified.

Guide

This guide shows the deployment of two versions of a Service. Traffic splitting is used to manage the gradual splitting of traffic from v1 to v2.

This example assumes that the following Gateway is deployed:

apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: prod-web
spec:
  gatewayClassName: acme-lb
  listeners:  
  - protocol: HTTP
    port: 80
    routes:
      kind: HTTPRoute
      selector:
        matchLabels:
          gateway: prod-web-gw   

Canary traffic rollout

At first, there may only be a single version of a Service that serves production user traffic for foo.example.com. The following HTTPRoute has no weight specified for foo-v1 or foo-v2 so they will implicitly recieve 100% of the traffic matched by each of their route rules. A canary route rule is used (matching the header traffic=test) to send synthetic test traffic before splitting any production user traffic to foo-v2. Routing precedence ensures that all traffic with the matching host and header (the most specific match) will be sent to foo-v2.

Traffic splitting

apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: foo-route
  labels:
    gateway: prod-web-gw
spec:
  hostnames:
  - foo.example.com
  rules:
  - forwardTo:
    - serviceName: foo-v1
      port: 8080
  - matches:
    - headers:
        type: Exact
        values:
          traffic: test
    forwardTo:
    - serviceName: foo-v2
      port: 8080  

Blue-green traffic rollout

After internal testing has validated succesful responses from foo-v2, it's desirable to shift a small percentage of the traffic to the new Service for gradual and more realistic testing. The HTTPRoute below adds foo-v2 as a backend along with weights. The weights add up to a total of 100 so foo-v1 recieves 90/100=90% of the traffic and foo-v2 recieves 10/100=10% of the traffic.

Traffic splitting

apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: foo-route
  labels:
    gateway: prod-web-gw
spec:
  hostnames:
  - foo.example.com
  rules:
  - forwardTo:
    - serviceName: foo-v1
      port: 8080
      weight: 90
    - serviceName: foo-v2
      port: 8080
      weight: 10  

Completing the rollout

Finally, if all signals are positive, it is time to fully shift traffic to foo-v2 and complete the rollout. The weight for foo-v1 is set to 0 so that it is configured to accept zero traffic.

Traffic splitting

apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: foo-route
  labels:
    gateway: prod-web-gw
spec:
  hostnames:
  - foo.example.com
  rules:
  - forwardTo:
    - serviceName: foo-v1
      port: 8080
      weight: 0
    - serviceName: foo-v2
      port: 8080
      weight: 1  

At this point 100% of the traffic is being routed to foo-v2 and the rollout is complete. If for any reason foo-v2 experiences errors, the weights can be updated to quickly shift traffic back to foo-v1. Once the rollout is deemed final, v1 can be fully decommissioned.

Back to top