Lesson 6 · Traffic, the edge & resilience
DestinationRule & subsets
What happens after routing — load balancing, subsets, and the session affinity that keeps chat working.
Your win: explain what a DestinationRule governs (load balancing, subsets,
connection pools, outlier detection), how subsets enable canary routing, and read the one
hand-written DestinationRule in this repo — tom's.
The policy that applies after routing
A VirtualService decides where a request goes (Lesson 4). A DestinationRule decides how it's delivered once the destination is chosen: which load-balancing algorithm, how big the connection pool may be, whether to eject unhealthy Pods, and which named subsets exist.1
| trafficPolicy field | Controls |
|---|---|
loadBalancer | ROUND_ROBIN / LEAST_REQUEST / consistentHash (affinity) |
connectionPool | max connections / requests — backpressure limits |
outlierDetection | eject Pods that error too often (circuit breaking, Lesson 7) |
tls | mTLS mode for calls to this host |
subsets | named Pod groups (by label) a VirtualService can target |
Subsets — the basis of version routing
A subset is a named subgroup of a service's Pods, selected by label
(e.g. version: v21 That's
the canonical canary pattern: 95% to v1, 5% to v2.
The split lives in the VirtualService; the subset definitions live in the
DestinationRule. They're a pair.
util.destinationrule.api.tpl
(deployments/helm/libs/util/templates/_hosts.tpl:68-80): it sets
host: .Values.service.grpcHost (:74),
portLevelSettings, and splices in .Values.trafficPolicy
(:79). Almost no backend service ships a DestinationRule — but
tom does
(backend/tom/templates/destinationrule.yaml). And its
trafficPolicy is the interesting bit:
loadBalancer.consistentHash.httpHeaderName: x-chat-userhash
(tom/values.yaml:67-70).
consistentHash load-balancing routes all requests with the same
x-chat-userhash header to the same Pod. Why? Because tom
holds chat/websocket state (it's a StatefulSet — Course 2 L7), so a user's messages must keep
landing on the Pod that has their session. Plain round-robin would scatter them and break
affinity. This is session affinity done at the mesh layer — and it's exactly the
kind of thing you can only do with a DestinationRule, not a plain Kubernetes Service.
connectionPool, outlierDetection,
or tls block. So in this repo, DestinationRules are used for
load-balancing policy (affinity), not circuit breaking or mTLS. Honest
framing: the capabilities exist; the repo uses one of them.
Istio docs — DestinationRule (reference)
trafficPolicy (load balancing, connection pool, outlier detection, tls) and subsets.
Check yourself (from memory)
Q1. A DestinationRule governs traffic…
Q2. Subsets are declared in a DestinationRule so that…
Q3. tom uses consistentHash on x-chat-userhash to…
trafficPolicy = loadBalancer (ROUND_ROBIN / LEAST_REQUEST / consistentHash),
connectionPool (limits), outlierDetection (eject unhealthy = circuit breaking), tls (mTLS
mode); plus SUBSETS = named Pod groups by label. SUBSETS + a VirtualService's weighted routes
= CANARY (95% v1 / 5% v2): split in the VS, subset defs in the DR. REPO: macro
util.destinationrule.api.tpl (_hosts.tpl:68); almost only
tom ships one — consistentHash.httpHeaderName: x-chat-userhash
(tom/values.yaml:67-70) = SESSION AFFINITY, so a user's chat/websocket keeps
hitting the same Pod (tom is a StatefulSet with session state). No connectionPool/outlier/tls
set — DRs here are for LB policy, not circuit breaking.