Session Affinity and Traffic Distribution

Which backend does a Service connection reach, and can you steer it? By default kube-proxy writes every ready endpoint into the rules and the dataplane picks one per connection, ignoring zones. Two fields change that: sessionAffinity ClientIP pins a client IP to one Pod while that Pod stays in the rules and the client reconnects within 10800s by default, and trafficDistribution PreferSameZone keeps only same-zone endpoints, or all ready ones if that zone has none.

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

Session Affinity and Traffic Distribution, Kubernetes diagram

Session Affinity and Traffic Distribution, step by step

  1. With both fields unset, kube-proxy writes every ready endpoint into the Service rules on the client Node and ignores zones. The dataplane picks a backend per connection, so two connections from one client can land in different zones, here zone-a and zone-b. Load spreads evenly, but traffic may cross the zone boundary.

    Play from step 1
  2. First lever, per client: set sessionAffinity to ClientIP. The opening connection still picks a backend freely, and the dataplane pins source 10.244.2.50 to the Pod it picked, 10.244.2.7. Later connections from that client return there while that Pod stays in the rules and the client reconnects within the sticky window, 10800 seconds by default.

    Play from step 2
  3. Second lever, per zone: set trafficDistribution to PreferSameZone (PreferClose is its deprecated alias). Each ready endpoint in the EndpointSlice carries a zone hint, and kube-proxy on this zone-a Node writes only the zone-a endpoints into its rules. The connection stays in zone-a, which can cut latency and cross-zone costs.

    Play from step 3
  4. PreferSameZone is a preference, not a hard rule. When zone-a has no ready endpoint, kube-proxy finds none hinted for its zone and writes every ready endpoint in the cluster instead, which here is only the two in zone-b. The connection crosses zones rather than failing. Availability wins over locality.

    Play from step 4

Sources