Introduction
A Service gets traffic to your pods once it’s already inside the cluster. But the request that started on someone’s laptop, hit your domain, and needs to land on the right Deployment? That’s the job of Ingress and, increasingly, the Gateway API — and it’s the part of the Certified Kubernetes Administrator Services & Networking domain that trips people up most.
The domain is worth roughly 20% of the CKA exam, and Kubernetes has been steadily modernizing how external traffic enters a cluster. Ingress is still the workhorse you’ll see everywhere, but the curriculum now explicitly calls out using the Gateway API to manage Ingress traffic — a signal that both models are fair game on exam day. If you can create an Ingress that path-routes to two backends, terminate TLS on it, and then reproduce the same routing with a Gateway and an HTTPRoute, you’ve covered the part of this domain candidates most often fumble.
This guide is written from a practitioner’s perspective. We’ll start with a quick Service refresher (because Ingress sits on top of Services), then go deep on Ingress resources and controllers, TLS, and the Gateway API — with the kubectl you’d actually type and the diagnostics that save you minutes you don’t have. If you want the full exam picture first, start with the CKA Exam Guide 2026 and the CKA domains breakdown, then come back here to go deep on traffic routing. For the Service, DNS, and CNI fundamentals, the CKA networking deep dive is the companion piece to this one.
Where Ingress Fits: A Quick Service Refresher
Before Ingress makes sense, anchor the four ways traffic reaches a pod:
| Type | Reachable from | Typical use |
|---|---|---|
| ClusterIP | Inside the cluster only | Default; internal service-to-service |
| NodePort | Any node IP on a high port (30000–32767) | Simple external exposure, dev/testing |
| LoadBalancer | External cloud load balancer | One service per external LB (cloud) |
| Ingress | External, via an HTTP(S) router | Many hostnames/paths behind one entry point |
The problem Ingress solves: without it, exposing ten microservices externally means ten LoadBalancer Services — ten cloud load balancers, ten bills. Ingress lets one entry point route to many Services by hostname and URL path, doing HTTP-aware routing (and TLS termination) that a plain Service can’t.
Critically, an Ingress resource does nothing on its own. It’s just routing rules. Something has to read those rules and actually proxy traffic — that’s the Ingress controller.
Ingress Controllers: Rules Need an Engine
The Ingress resource is the configuration; the Ingress controller is the running software (typically NGINX, but also HAProxy, Traefik, or a cloud-native controller) that watches Ingress objects and programs itself accordingly.
Two facts the exam loves:
- A cluster ships with no Ingress controller by default. If you create an Ingress and nothing happens, the first question is “is a controller installed?”
- The controller runs as pods in the cluster — usually a Deployment or DaemonSet in its own namespace — fronted by a
LoadBalancerorNodePortService.
Check whether one exists:
kubectl get pods -A | grep -i ingress
kubectl get ingressclass
The IngressClass object is how you tell an Ingress which controller should handle it — essential when a cluster runs more than one. One class is usually marked default via the ingressclass.kubernetes.io/is-default-class: "true" annotation.
The Ingress Resource: Path and Host Routing
Here’s the object you’ll write on the exam. This routes by URL path to two different Services:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: web
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
The imperative shortcut is a huge time-saver under exam pressure — generate the skeleton and edit it rather than typing all that YAML:
kubectl create ingress app-ingress \
--class=nginx \
--rule="app.example.com/api*=api-svc:80" \
--rule="app.example.com/*=frontend-svc:80"
pathType is not optional — and it’s a common trap
pathType has three values, and choosing wrong is a classic silent failure:
| pathType | Matches |
|---|---|
| Prefix | URL path prefix, split on / (e.g. /api matches /api/users) |
| Exact | The exact path only, case-sensitive |
| ImplementationSpecific | Left to the controller’s own logic |
Use Prefix for the everyday “everything under /api” case. Forgetting pathType entirely makes the manifest invalid — the API server rejects it.
Host-based routing and the default backend
Omit host and the rule matches any hostname. Provide multiple rules with different host values to fan out by domain — api.example.com to one Service, shop.example.com to another, all behind a single Ingress and a single external IP. A defaultBackend catches requests that match no rule, handy for a custom 404 service.
Inspect what the controller actually programmed:
kubectl describe ingress app-ingress -n web
# Confirm the Address (external IP), Rules, and Backends are populated
TLS Termination on an Ingress
The exam may ask you to serve HTTPS. Ingress terminates TLS using a kubernetes.io/tls Secret that holds the certificate and key:
kubectl create secret tls app-tls \
--cert=tls.crt --key=tls.key -n web
Then reference it:
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 443
The hosts in the tls block must match the host in the rule, and the Secret must live in the same namespace as the Ingress. A cert/host mismatch is a favorite gotcha — the browser gets served the wrong (or default) certificate.
The Gateway API: The Modern Successor
Ingress works, but it’s limited: advanced routing (headers, weights, traffic splitting) lives in controller-specific annotations, which don’t port between controllers. The Gateway API is the successor — a more expressive, role-oriented, and portable model, and it’s now part of the CKA curriculum. You don’t need to abandon Ingress, but you must be able to read and write the core Gateway objects.
The Gateway API splits Ingress’s single responsibility into three objects owned by different roles:
| Object | Owned by | Responsibility |
|---|---|---|
| GatewayClass | Infrastructure provider | Which controller implements Gateways (like IngressClass) |
| Gateway | Cluster operator | The actual listener: ports, protocols, TLS |
| HTTPRoute | Application developer | Routing rules: hostnames, paths → backend Services |
This separation is the whole point: a platform team owns the Gateway (the entry point and its TLS), while app teams attach HTTPRoutes to it without touching shared infrastructure.
A minimal Gateway:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: web-gateway
namespace: web
spec:
gatewayClassName: nginx
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
And an HTTPRoute that attaches to it and path-routes — the direct analog of the Ingress above:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
namespace: web
spec:
parentRefs:
- name: web-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-svc
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend-svc
port: 80
Note the shape differences from Ingress: routing lives in HTTPRoute.rules[].matches, backends are backendRefs (which can carry a weight for traffic splitting — something raw Ingress can’t do without annotations), and the route explicitly attaches to a Gateway via parentRefs. That attachment model is the conceptual leap; practice it until it’s muscle memory.
Verify the wiring:
kubectl get gatewayclass
kubectl get gateway -n web
kubectl describe httproute app-route -n web
# Check the Gateway's PROGRAMMED condition and the HTTPRoute's Accepted condition
Ingress vs. Gateway API at a glance
| Aspect | Ingress | Gateway API |
|---|---|---|
| API group | networking.k8s.io/v1 | gateway.networking.k8s.io/v1 |
| Objects | One (Ingress) | Three (GatewayClass, Gateway, HTTPRoute) |
| Role separation | None (one object, one owner) | Explicit (infra / operator / app) |
| Traffic splitting | Annotations only | Native weight on backendRefs |
| Protocols | HTTP/HTTPS focus | HTTP, TLS, TCP, UDP via route types |
| Portability | Controller-specific annotations | Standardized fields |
The one-line exam framing: Ingress is the established default; the Gateway API is the more expressive, portable, role-separated successor — and both can route the same traffic.
Troubleshooting: When External Traffic Won’t Land
Traffic routing fails in a handful of predictable ways. Work them top-down:
# 1. Does the Ingress have an external Address yet?
kubectl get ingress -n web # ADDRESS empty => controller not ready/installed
# 2. Is a controller actually running?
kubectl get pods -A | grep -i ingress
# 3. Does the Ingress reference a real Service and port?
kubectl describe ingress app-ingress -n web
# 4. Is the backend Service selecting any pods?
kubectl get endpoints api-svc -n web # No endpoints => selector/label mismatch
# 5. Are the backend pods actually Ready?
kubectl get pods -n web -o wide
The single most common root cause isn’t the Ingress at all — it’s an empty Endpoints list because the Service’s selector doesn’t match the pods’ labels. Ingress faithfully routes to a Service that routes to nothing. Always walk the chain Ingress → Service → Endpoints → Pods; the break is usually further down than you first assume. The CKA troubleshooting guide drills this systematic approach across the whole exam.
For the Gateway API, the equivalent checks are the Gateway’s PROGRAMMED condition and the HTTPRoute’s Accepted/ResolvedRefs conditions — kubectl describe surfaces both, and a False there tells you whether the listener or the route binding is the problem.
Exam-Day Speed Tips
- Generate, don’t type.
kubectl create ingress ... --rule=...scaffolds the manifest; edit the output rather than writing YAML from memory. - Set the class. An Ingress with no
ingressClassNamein a multi-controller cluster may be silently ignored. Checkkubectl get ingressclassfirst. - Remember
pathType. Omitting it fails validation; defaulting toPrefixis right most of the time. - Same-namespace Secrets. TLS Secrets and the Ingress must share a namespace.
- Know both models. If a task says “using the Gateway API,” reach for
Gateway+HTTPRoute, notIngress. Read the prompt for which one it wants. - Bookmark the docs. Ingress and Gateway API pages on kubernetes.io are allowed during the exam — the CKA kubectl cheat sheet and the official docs together cover the exact YAML shapes.
Practicing This Domain Under Real Conditions
Ingress and the Gateway API are muscle-memory skills — you don’t truly know them until you’ve created a Gateway, attached an HTTPRoute, watched the PROGRAMMED condition flip to True, and curled the result under a ticking clock. Reading YAML isn’t the same as producing it in a live cluster in ninety seconds.
That’s the gap timed, hands-on practice closes. The Certified Kubernetes Administrator (CKA) Mock Exam Bundle on Sailor.sh puts you in browser-based clusters with realistic Services & Networking tasks — build the Ingress, terminate TLS, reproduce the routing with the Gateway API, then diagnose why traffic isn’t landing — so exam day feels like a rerun of something you’ve already done. Pair it with the free practice walkthrough in how to practice CKA for free to build the reps before you sit the real thing.
Conclusion
The traffic-routing slice of the CKA Services & Networking domain rewards a specific, reproducible skill set: expose Services correctly, layer an Ingress on top for host- and path-based HTTP routing, terminate TLS with a same-namespace Secret, and reproduce the whole thing with the Gateway API’s Gateway + HTTPRoute model. Learn to walk the Ingress → Service → Endpoints → Pods chain when traffic won’t land, and you’ll solve the failures faster than candidates who only memorized the happy path.
Ingress remains the default you’ll meet most often; the Gateway API is where Kubernetes networking is heading, and the exam now expects fluency in both. Practice each until the YAML flows without thinking — then the 20% this domain is worth becomes some of the easiest points on the test. From here, round out the domain with the CKA networking deep dive for Services, DNS, and network policies, and the CKA study plan to slot this into a full prep timeline.
FAQ
Does the CKA exam include the Gateway API?
Yes. The current CKA curriculum explicitly lists using the Gateway API to manage Ingress traffic alongside classic Ingress resources. You should be comfortable creating a Gateway and an HTTPRoute, not just an Ingress. Both models can appear, so learn to recognize which one a task is asking for.
What’s the difference between an Ingress and an Ingress controller?
The Ingress resource is configuration — a set of routing rules stored in the API server. The Ingress controller is the running software (NGINX, Traefik, etc.) that watches those rules and actually proxies traffic. A cluster has no controller by default, so creating an Ingress with no controller installed does nothing.
Why does my Ingress have no external address?
Almost always because no Ingress controller is running, or its fronting Service hasn’t been assigned an external IP. Run kubectl get pods -A | grep -i ingress to confirm a controller exists and kubectl get ingressclass to confirm a class is available and referenced by your Ingress.
My Ingress returns 503 — what’s wrong?
A 503 usually means the backend Service has no healthy endpoints. Run kubectl get endpoints <service>; if it’s empty, the Service selector doesn’t match your pod labels, or the pods aren’t Ready. Fix the label/selector or the failing readiness probe — the Ingress itself is fine.
Do I need to memorize Ingress controller annotations for the CKA?
No. The CKA tests portable, core-API skills — the Ingress and Gateway API objects themselves, not controller-specific annotations (which vary by vendor). Focus on pathType, host/path rules, TLS Secrets, and the Gateway/HTTPRoute model. The official kubernetes.io docs are available during the exam for exact field names.
Should I still learn Ingress if the Gateway API is the future?
Yes. Ingress is deployed across virtually every existing cluster and remains fully supported and testable. Learn Ingress as the default, then add the Gateway API as the modern, more expressive successor. On the exam, knowing both is the safe position.