Lesson 07 of 13 · Architecture
Load balancing & ingress
Design how traffic reaches ParcelPath's services: L4 load balancing for the API server and ingress, L7 routing with an ingress controller or Gateway API, where TLS terminates (edge, ingress, pod) and why, preserving client IPs, and an ADR for the TLS choice.
The traffic path
client ─► DNS (GSLB, lesson 12) ─► edge (CDN/WAF, lesson 08) ─► L4 VIP (MetalLB BGP)
─► ingress controller / Gateway (L7, TLS) ─► Service ─► pods
Traffic to a big stadium: the car park gates (L4) only check that you're heading to the right gate number and spread cars across lanes. Ushers inside (L7) read your ticket (host, path), check it's genuine (TLS), and walk you to the right seat. Where you check tickets, and whether people stay "in a sealed corridor" all the way to their seat (re-encryption), are design choices.
L4: stable IPs
- API server: a VIP (kube-vip) or an external LB in front of the three control-plane nodes (lesson 05).
- Ingress tier:
type: LoadBalancerServices with MetalLB in BGP mode peering with the ToR switches (ECMP spreads traffic across ingress nodes), or existing hardware/virtual load balancers if the organisation standardises on them. - Run the ingress controller on the dedicated system pool (lesson 05), at least one replica per rack.
L7: ingress or Gateway API
- A mature ingress controller (NGINX-based, HAProxy, Envoy-based, Traefik…) or a Gateway API implementation (see Kubernetes Security & Hardening, lesson 08).
- Gateway API separates infrastructure (GatewayClass, Gateway owned by the platform team) from routes (HTTPRoute owned by app teams), which fits ParcelPath's team model.
- Configure timeouts, request size limits, retries (idempotent requests only) and connection limits deliberately.
Where does TLS terminate?
| Option | Pros | Cons |
|---|---|---|
| External LB/WAF only | Central cert management, WAF inspection | Plaintext inside the DC unless re-encrypted |
| Ingress (cert-manager) | Kubernetes-native, automated renewal, L7 features | Keys live in the cluster (protect Secrets) |
| Ingress + re-encrypt / mesh mTLS | Encrypted end to end | More certificates and CPU; mesh complexity |
| Passthrough (SNI) | App controls the key | No L7 routing/policy at ingress |
ADR-004: TLS termination for customer-facing traffic
Status: Accepted
Context
NFR-06 requires TLS 1.2+ externally; the security team requires encryption between
network zones. The WAF (lesson 08) needs to inspect HTTP. Certificates must renew
automatically.
Decision
TLS terminates at the WAF (public certificate) and is re-established from the WAF to the
ingress (internal CA via cert-manager). Ingress to pods is plaintext inside the cluster for
now, protected by NetworkPolicies; mesh mTLS is evaluated in phase 2.
Consequences
+ WAF can inspect traffic; certificates renew automatically at both hops.
− Two certificate chains to operate; in-cluster traffic unencrypted until phase 2
(accepted risk, reviewed in 6 months).
Alternatives
Passthrough to pods: no WAF inspection. Terminate only at WAF: plaintext across zones.
Client IP and health
externalTrafficPolicy: Localon the ingress Service keeps the client IP and avoids an extra hop; MetalLB/LB health checks route only to nodes with ready ingress pods.- Behind an L4 LB that terminates TCP, use the PROXY protocol (or
X-Forwarded-Forfrom an L7 LB) so the ingress sees the real client IP. - Size the ingress tier for connections and TLS handshakes per second, not just requests.
Try it: L4 + L7 in the lab
- Install MetalLB (L2 mode in the lab) and an ingress controller with a
LoadBalancerService. - Install cert-manager with a self-signed ClusterIssuer and issue a certificate for an Ingress/HTTPRoute.
- Compare the source IP seen by a backend with
externalTrafficPolicy: ClustervsLocal. - Configure a timeout and a request size limit, and test both with curl.
- Write ADR-004 for your own environment, including one rejected alternative.
Going deeper: ingress at scale
- Separate public and internal ingress tiers (different IPs, policies and blast radius).
- Watch ingress reload behaviour: some controllers reload on every config change; at scale, prefer dynamic configuration.
- Load-test the ingress tier with realistic TLS (new connections vs keep-alive) during the PoC (lesson 02).
Recap
- L4 (MetalLB BGP, kube-vip, hardware LB) gives stable IPs; L7 (ingress/Gateway API) routes HTTP and terminates TLS.
- Choose TLS termination points deliberately (edge, ingress, re-encrypt, passthrough) and record an ADR.
- Preserve client IPs (
externalTrafficPolicy: Local, PROXY protocol); size for handshakes and connections.
This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.