Build a Service Mesh (Envoy / Istio style) (13 scenes)
Scene 02 · The sidecar — one proxy per pod
Put a small proxy next to every service. App talks to localhost; cross-service traffic flows sidecar to sidecar. The fleet of sidecars is the service mesh.
Previously

Taking the network out of fifty apps' hands means putting a single, identical piece of code next to each app and routing every request through it.

Scene 02
The sidecar — one proxy per pod
Diagram
Two pods sit side-by-side. Each pod is a dashed frame holding an App container (gray, owns business logic) and a Sidecar container (green, owns policy). A request animates from App A through Sidecar A on localhost, across the network to Sidecar B, and into App B. **Sidecar** = a second container in the same pod that intercepts the app's traffic. **Service mesh** = the fleet of every sidecar across your services, treated as one configurable system — visible when you zoom out to the 12-pod view.
WITH SERVICE MESHPOD AApp Aowns business logicSIDECARSidecar Aowns policyPOD BApp Bowns business logicSIDECARSidecar Bowns policylocalhostlocalhostnetwork · mTLSSHARED SIDECAR POLICYretry budget: 20% of in-flight · mTLS: requiredApp → Sidecar (localhost) → Sidecar → App. Both sidecars read the same shared policy.
the app keeps doing business logic, so the policy box sits next to it as a separate process — that process is the *sidecar*.
Watch one request travel through two pods. It leaves App A, drops into Sidecar A on localhost, crosses the network to Sidecar B (mTLS), then surfaces in App B. The sidecars — not the apps — own the policy on that hop.
Implementation
App A — unchanged after sidecar
the app still calls a hostname; it does not know about any sidecar
1def handle_request():
2 # App still calls a hostname.
3 # It does not know there's a sidecar.
4 response = http.get('checkout-svc/cart')
5 return render(response)
iptables on Pod A (istio-init)
kernel-level redirect of outbound traffic onto the sidecar listener
1# Installed by the istio-init container at pod start.
2iptables -t nat -N ISTIO_OUTPUT
3iptables -t nat -A OUTPUT -p tcp -j ISTIO_OUTPUT
4# Skip traffic the sidecar itself originates (uid 1337).
5iptables -t nat -A ISTIO_OUTPUT -m owner \
6 --uid-owner 1337 -j RETURN
7# Everything else from the app: redirect to Envoy on 15001.
8iptables -t nat -A ISTIO_OUTPUT -p tcp \
9 -j REDIRECT --to-ports 15001
Sidecar A — outbound loop
owns the call once iptables hands it over (retry, timeout, mTLS)
1def serve_outbound():
2 conn = accept(':15001') # from iptables REDIRECT
3 req = http.parse(conn)
4 route = routes.match(req) # listener -> route
5 for attempt in range(route.retry_budget):
6 upstream = mtls.dial(route.cluster, deadline=route.timeout)
7 resp = upstream.send(req)
8 if not retryable(resp): break
9 http.write(conn, resp)
Sidecar B — inbound loop
terminates mTLS, then forwards to the local app on localhost
1def serve_inbound():
2 conn = accept(':15006') # inbound REDIRECT target
3 peer = mtls.terminate(conn) # verify Sidecar A's cert
4 req = http.parse(conn)
5 upstream = dial('127.0.0.1:app_port')
6 resp = upstream.send(req)
7 http.write(conn, resp)