Traffic Splitting with HTTPRoute

How does a Gateway send a tenth of traffic to a new version? An HTTPRoute rule lists several backendRefs with weights, and each Service gets its weight divided by the sum of the weights whatever its Pod count, while a rule matching a test header can send only tagged requests there first. A backendRef that does not resolve keeps its share, which must get HTTP 500, and a weight of 0 on the old version completes the cutover.

Play the animation 5 steps, animated, best on a wide screen

Traffic Splitting with HTTPRoute, Kubernetes diagram

Traffic Splitting with HTTPRoute, step by step

  1. An HTTPRoute attached to the Gateway shop has one rule with no match, so it takes every path, and it lists one backendRef, Service web-v1, with no weight. An unset weight defaults to 1, and a lone backend with a weight above 0 takes every request. The Gateway sends each one to a Pod behind that Service, by the Service IP or an endpoint, as its implementation chooses.

    Play from step 1
  2. Before users see web-v2, a second rule matches the header traffic: test and lists web-v2 alone. Both rules match the path prefix / and neither names a method, so the tie goes to the rule with more header matches. Only a request carrying that header reaches the one Pod of web-v2, and every other request still takes the default rule to web-v1.

    Play from step 2
  3. The default rule now lists web-v1 with weight 90 and web-v2 with weight 10. A weight is a proportion, not a percentage: each backend gets its weight divided by the sum, 90 of 100 and 10 of 100, and the sum need not be 100. One request is drawn down each leg, but the split is far from even: whatever the replica counts, the one Pod of web-v2 gets about a tenth of the requests this rule matches, and three Pods share the rest.

    Play from step 3
  4. If instead web-v2 did not resolve, say its Service were deleted, the route would report ResolvedRefs False. The tenth of requests weighted to web-v2 must then get HTTP 500, and so must every request of the header rule, which lists web-v2 alone and has no filters. That tenth is not handed to web-v1, which still serves its 90 of 100.

    Play from step 4
  5. Back in the real rollout, where web-v2 resolves, the weights become 0 for web-v1 and 1 for web-v2. A weight of 0 forwards no traffic, so web-v2 takes every request. The Pods of web-v1 are still running, so shifting traffic back is one edit to the weights.

    Play from step 5

Sources