Beyond Round-Robin
Standard Kubernetes Service load balancing is deliberately simple: it uses round-robin across all healthy pods. If you have 10 pods, each gets roughly 10% of traffic. There is no concept of "send 5% to the new version."
A service mesh gives you fine-grained traffic control because the sidecar proxy — not the kernel's kube-proxy — handles the routing decision. You express your intent in a declarative configuration object (in Istio, a VirtualService), and the control plane translates that into Envoy routing rules.
Canary Deployment — a concrete example:
You have payment-service v1 running in production. You deploy payment-service v2 alongside it. You want to test v2 with real traffic but limit the blast radius if it has bugs. A traffic-splitting rule expresses this as a weighted split between the two versions — say 95% of requests to v1, 5% to v2 — which every Envoy sidecar in the cluster then enforces. If v2 starts returning errors, you change the weights back to 100/0 and push the updated rule. The rollback takes seconds and requires no redeployment.
Header-based routing is another powerful pattern. You can route requests that contain the header X-Beta-User: true to v2, and all other requests to v1. This lets you test new features with a specific group of users (internal testers, beta customers) without affecting anyone else — a technique called dark launching.
The key insight is that traffic splitting in a service mesh is decoupled from deployment. You can have 50 v2 pods and still send them 1% of traffic. The mesh controls the split independently of how many replicas exist.