Ingress & Load Balancing
Services route traffic inside the cluster, but Ingress routes external HTTP(S) traffic to Services by hostname and path, with TLS termination. Learn the Ingress resource, the NGINX controller and the annotations that make it work.
What is this?
Ingress is a Kubernetes API resource that describes how external HTTP(S) traffic should reach Services, using rules for hostnames and URL paths. An Ingress resource alone does nothing: a running Ingress controller (commonly NGINX) watches Ingress objects and configures itself to enforce the rules. This centralizes routing, TLS termination and path rewriting in one layer in front of many Services.
Why do you need it?
- One external entry point can route to many Services by hostname and path instead of one NodePort per Service.
- TLS termination happens at the Ingress, so applications do not each manage certificates.
- Rules are declarative and versioned like the rest of your manifests.
- Advanced features like canary routing, rate limiting and rewrites come from controller annotations.
Mental model
A reception desk in a big office building
An Ingress controller
Visitors arrive at one address and say which company and floor they want. The receptionist (controller) reads the visitor's request (hostname and path) and directs them to the right office (Service).
How it works
- You create an Ingress resource declaring rules: which hosts and paths map to which Services.
- An Ingress controller (for example ingress-nginx) watches for Ingress objects via the API server.
- The controller programs its proxy configuration so traffic matching a host/path is forwarded to the right Service.
- Traffic flows client → Ingress controller → Service ClusterIP → pod.
- TLS secrets attached to the Ingress are used by the controller to terminate HTTPS.
External HTTP traffic routed through an Ingress controller.
Key commands
kubectl apply -f ingress.yamlCreate or update an Ingress resource from a manifest.
kubectl get ingressList Ingress resources with hosts and addresses.
NAME CLASS HOSTS ADDRESS PORTS AGE app-ingress nginx app.example.com 192.168.49.2 80 2m
kubectl describe ingress app-ingressShow rules, backends and annotations.
curl -H "Host: app.example.com" http://<ingress-ip>/Test host-based routing by sending the Host header directly.
kubectl get pods -n ingress-nginxConfirm the Ingress controller pods are running.
kubectl logs -n ingress-nginx deployment/ingress-nginx-controllerRead the controller logs to debug routing.
Examples
Host-based routing with the NGINX controller
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: app-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: ingressClassName: nginx rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: app-svc port: number: 80This Ingress tells the NGINX controller to route requests for app.example.com to the app-svc Service on port 80. ingressClassName: nginx selects the NGINX controller when several controllers are installed, and the rewrite-target annotation strips the matched prefix before forwarding.
In production
- A single Ingress controller terminates TLS and routes all public traffic to dozens of microservices.
- Path-based rules expose /api to one service and / to a web frontend on the same host.
- Controller annotations enable canary releases by routing a percentage of traffic to a new service.
- TLS secrets (kubernetes.io/tls type) attach certificates per hostname, with automatic renewal via cert-manager.
Best practices
- Always set ingressClassName so the correct controller picks up the resource.
- Use explicit pathType (Prefix or Exact) to avoid ambiguous routing rules.
- Terminate TLS at the Ingress with a kubernetes.io/tls Secret and redirect HTTP to HTTPS.
- Test host routing with curl -H "Host: ..." before touching DNS.
- Put the Ingress in the same namespace as its backend Services or use fully-qualified service names.
Common mistakes
- Creating an Ingress without installing any controller, then wondering why nothing routes.
- Forgetting ingressClassName when multiple controllers share the cluster.
- Serving a default backend 404 because the hostname in the rule does not match the request.
- Typing the rewrite-target annotation wrong, causing paths to double or vanish.
Common issues
404 Not Found from the IngressNo rule matches the request, the backend Service has no endpoints, or the path/type is wrong.
Describe the Ingress, verify the backend Service endpoints, and align host, path and pathType.
Ingress has no ADDRESS and rules are not appliedNo Ingress controller is installed, or ingressClassName does not match the controller.
Install a controller (e.g. minikube addons enable ingress) and set ingressClassName: nginx.
certificate is valid for app.example.com, not for <host>The TLS Secret contains a certificate for the wrong hostname.
Reissue the certificate for the exact hostname in the rule and recreate the kubernetes.io/tls Secret.
Debugging tips
- kubectl get ingress -o yaml and kubectl describe ingress reveal the rules and backend references.
- curl -H "Host: app.example.com" http://<ingress-ip>/ bypasses DNS to test the rule directly.
- kubectl get endpoints <svc> confirms the backend Service actually has pods.
- Read controller logs in the ingress controller namespace for routing and TLS errors.
Interview checkpoint
Hands-on lab
- Enable the NGINX Ingress controller
- Deploy two backend Services
- Create host-based Ingress rules
- Verify routing from outside the cluster
Route Traffic with the NGINX Ingress Controller
40 min · advanced
Quick quiz
Which component actually routes traffic in an Ingress setup?
An Ingress can route based on both hostnames and URL paths.
Which field selects which Ingress controller handles an Ingress?
Cheat sheet
kubectl apply -f ingress.yamlCreate/update an Ingresskubectl get ingressHosts, address, portskubectl describe ingress NAMERules and backendskubectl get ingress -n ingress-nginxIngress objects the controller seescurl -H "Host: app.local" http://IP/Test routing without DNS