Skip to main content
Course/Storage & Ingress/Ingress
4/775 min
Storage & Ingress

Ingress

Route external HTTP/HTTPS traffic to multiple services with a single entry point and path-based rules.

intermediate75 minRead β†’ Lab β†’ Quiz β†’ Practice
🧠 Brain Warm-Up
🧠 Brain Warm-Up: When a client sends an HTTP request to myapp.local/api via Ingress, does the Ingress Controller forward the packet to the Service's ClusterIP, or does it bypass the Kubernetes service mesh routing? How does this impact load-balancing algorithms and connection keep-alives?

The Problem with NodePort and LoadBalancer

NodePort: exposes a high-numbered port (30000–32767) on every node. Not suitable for production β€” users should not type myapp.com:31234.

LoadBalancer: creates one cloud load balancer per Service. If you have 10 microservices, you pay for 10 load balancers. That is expensive and hard to manage.

Ingress: N Services, One Entry Point

Ingress is a Kubernetes resource that defines HTTP/HTTPS routing rules. It acts like a virtual host configuration for a reverse proxy:

Internet β†’ LoadBalancer β†’ IngressController β†’ (routing rules) β†’ Service A
                                                               β†’ Service B
                                                               β†’ Service C

One cloud load balancer handles all traffic. The IngressController applies your rules.

Two Components

ComponentWhat it is
Ingress resourceA Kubernetes object containing routing rules (host, path β†’ Service)
IngressControllerA running reverse proxy (nginx, Traefik, HAProxy, AWS ALB) that reads those rules and routes real traffic

Important: creating an Ingress resource without an IngressController does nothing. The IngressController must be installed separately.

Path Types

TypePath `/api` matches
ExactOnly /api (not /api/users)
Prefix/api, /api/users, /api/v2/items

TLS Termination

Reference a kubernetes.io/tls Secret to enable HTTPS at the Ingress:

spec:
  tls:
  - hosts:
    - myapp.local
    secretName: myapp-tls

Create the Secret with: kubectl create secret tls myapp-tls --cert=tls.crt --key=tls.key

The IngressController handles the TLS handshake. Backend Services receive plain HTTP β€” they do not need to know about TLS.

Annotations

Controller-specific behaviour (rate limiting, rewrites, auth) is configured via annotations:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/limit-rps: "10"

These are read by the IngressController β€” not by Kubernetes itself.


L7 Routing & TLS Termination Flow

         [ Client HTTPS Request ]
             (Host: myapp.local)
                     |
                     v
  +------------------+-------------------+
  | Cloud Load Balancer (TCP Pass-Through)|
  +------------------+-------------------+
                     | (TLS Encrypted, Port 443)
                     v
  +------------------+-------------------+
  |      Ingress-Nginx Controller        |
  |  - TLS Handshake (SNI Match via SNI) |
  |  - Decrypts and injects headers      |
  |  - Fetches Pod IPs from EndpointSlice| (Bypasses Service IP!)
  +-------+---------------------+--------+
          |                     |
          v (Plain HTTP / L7)   v (Plain HTTP / L7)
  +-------+------------+   +----+---------------+
  |  Pod: Web-0        |   |  Pod: Web-1        |
  |  (10.244.1.5:80)   |   |  (10.244.2.9:80)   |
  +--------------------+   +--------------------+

Under the Hood: L7 Ingress Routing Internals

1. ClusterIP Bypass & Direct Endpoint Routing

Rather than proxying requests to the virtual IP (ClusterIP) of the backend Service, most Ingress Controllers bypass kube-proxy entirely. The Ingress Controller queries the API server for Endpoints or EndpointSlices associated with the target Service. It maintains a direct list of backend Pod IPs and forwards connections straight to them. This enables:

  • Advanced L7 load-balancing algorithms (e.g., cookie-based session affinity, least-connections, hashing).
  • Optimal TCP connection pooling and keep-alive management, avoiding the extra packet translation overhead of NAT routing.

2. SNI Match & TLS Handshake

For HTTPS ingress, client handshakes terminate directly at the Ingress Controller. Using Server Name Indication (SNI), the controller extracts the requested hostname from the ClientHello handshake packet. It loads the corresponding kubernetes.io/tls certificate, decrypts the request, injects standard proxy headers (X-Forwarded-For, X-Forwarded-Proto, and X-Real-IP), and streams the decrypted payload to the backend Pod endpoint.

3. Dynamic Reloading

Modern ingress controllers (like Ingress-Nginx) avoid restarting the web server process during endpoint updates. They use a Go sidecar or embedded Lua engines (OpenResty) to dynamically refresh backend Pod IPs in shared memory tables without dropping active TCP connections.