Two directions of traffic
Chapter 16 built the basics: a Service gives pods a stable address (16.1), an Ingress plus a controller routes HTTP from outside to Services (16.19), and Gateway API splits that job across objects owned by different teams (16.26). This chapter goes one level down, into the parts that page you at night.
What you need to know already: Services and EndpointSlices (16.1), LoadBalancer and MetalLB (16.6), Ingress, the controller and IngressClass (16.19), TLS termination and SNI (16.22, 9.15), Gateway API's GatewayClass, Gateway and HTTPRoute (16.26), NetworkPolicy (16.29), HTTP status codes and proxies (9.21-9.23).
Platform people sort traffic by where it comes from:
- North-south traffic crosses the edge of the cluster: a customer's browser, a partner's API client, a webhook from a payment provider. It enters through an edge proxy (an ingress controller, a Gateway's data plane) that terminates TLS and routes by host and path.
- East-west traffic stays inside: the web front end calling the cart service, the cart calling inventory. It used to be "just a ClusterIP" (16.3). A service mesh puts a proxy next to every pod, so east-west calls get the same things the edge has: TLS, identity, retries, timeouts, per-request logs.
north-south
browser ──TLS──> [ edge proxy ] ──> web ──> cart ──> inventory
ingress-nginx └──── east-west ────┘
or a Gateway (ClusterIP, or a mesh)
The words are old data-centre slang: diagrams drew the internet at the top (north) and the servers in a row (east to west).
L4 and L7
A proxy works at one of two levels:
- L4 (layer 4, TCP/UDP): it sees connections and ports. kube-proxy's rules (16.3), a NodePort, MetalLB and most cloud network load balancers are L4. They can spread connections but cannot read a URL or a header.
- L7 (layer 7, HTTP): it parses each request. nginx, Envoy, HAProxy are L7. Only L7 can route
/apiand/to different Services, retry one failed request, or return 503 with a reason.
The cost of L7 is that the proxy must see the bytes - so it must hold the TLS key, or the traffic must be plaintext by the time it gets there.
Where TLS ends
Three patterns, all common:
edge termination client ─TLS─> proxy ─HTTP─> pod the proxy holds the cert (16.22)
re-encrypt client ─TLS─> proxy ─TLS──> pod the proxy also talks TLS to the pod
passthrough client ─TLS──────────────> pod the proxy routes by SNI only (L4-ish)
A mesh adds a fourth: mTLS between sidecars - the app talks plain HTTP to its own sidecar on localhost, and the two sidecars encrypt and authenticate the hop between them. No app change, every hop encrypted.
Who owns what in this chapter
piece what it does team that usually owns it
ingress-nginx L7 edge proxy driven by Ingress objects platform (retired project!)
cert-manager gets and renews TLS certificates platform
external-dns writes DNS records for your entry points platform
Gateway API the successor API for the edge platform (Gateway) + apps (routes)
Istio (a mesh) a proxy per pod: mTLS, policy, retries platform + SRE
You will run all of them in the lab cluster, and break each one the way it breaks in production.
The status codes you will chase
Every edge or mesh proxy answers with a status code even when your app never saw the request. Knowing who produced a 503 is half the diagnosis:
404 the proxy found no route for this host/path (the app was never asked)
502 the proxy reached a pod, but the connection broke (refused, reset, bad TLS)
503 the proxy had nowhere to send it (no endpoints, no healthy upstream)
504 the proxy waited for an answer and gave up (a timeout you can configure)
The rest of the chapter adds the proxy's own evidence for each: nginx's error log line, Envoy's response flag in the access log, a Gateway's status condition.
What you can now do:
- say whether a flow is north-south or east-west, and which proxy handles it
- tell an L4 balancer from an L7 proxy by what it can see
- name where TLS ends in edge termination, re-encrypt, passthrough and mesh mTLS