Route /app and /admin to Two Services with an Ingress
Two backend services already exist in namespace cka-ingress: app-service (port 80) admin-service (port 80) An NGINX Ingress Controller is already installed in the cluster.
Live lab access
This task description is public. Its live lab requires full access; six other CKA labs are available in Free Practice with AI Lab Coach.
Create an account to continue →
Explore the six free labs with AI Lab Coach →
Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.
The task
Two backend services already exist in namespace cka-ingress:
app-service(port 80)admin-service(port 80)
An NGINX Ingress Controller is already installed in the cluster.
Task: Create an Ingress resource named app-ingress in namespace cka-ingress that:
- Uses
ingressClassName: nginx - Routes path
/apptoapp-serviceon port80 - Routes path
/admintoadmin-serviceon port80 - Uses
pathType: Prefixfor both rules
Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster. It needs an Ingress controller; an Ingress object on its own does nothing.
How an Ingress matches host and path: Exact, Prefix and the IngressClass
An Ingress is a list of rules, each pairing an optional host with paths, and each path with a Service and port. A controller, chosen through spec.ingressClassName, reads those rules and configures its proxy. Most routing surprises come from two places: which class picks the object up, and how pathType compares the request path. The Ingress API is frozen (new features go to Gateway API), but it is still on the CKA curriculum and widely used.
request Host + path ──→ controller for the IngressClass
books.prepium.test /healthz (Exact) ──→ Service ping:8080
books.prepium.test /shelf... (Prefix) ──→ Service shelf:8080
maps.prepium.test /... (Prefix) ──→ Service atlas:8080
1. Create backends that say who they are
kubectl create namespace prepium-tutorial
for s in ping shelf atlas; do
kubectl -n prepium-tutorial run $s --image=hashicorp/http-echo:1.0 --labels=app=$s -- -text=$s
kubectl -n prepium-tutorial expose pod $s --port=8080 --target-port=5678
done
kubectl get ingressclass
http-echo answers every path with its -text value, so each response names the backend that served it. Note the IngressClass name from the last command; a class marked with ingressclass.kubernetes.io/is-default-class: "true" is used when an Ingress omits the field.
2. Write rules for two hosts
IC=$(kubectl get ingressclass -o jsonpath='{.items[0].metadata.name}')
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: library
namespace: prepium-tutorial
spec:
ingressClassName: $IC
rules:
- host: books.prepium.test
http:
paths:
- path: /healthz
pathType: Exact
backend: {service: {name: ping, port: {number: 8080}}}
- path: /shelf
pathType: Prefix
backend: {service: {name: shelf, port: {number: 8080}}}
- host: maps.prepium.test
http:
paths:
- path: /
pathType: Prefix
backend: {service: {name: atlas, port: {number: 8080}}}
EOF
kubectl -n prepium-tutorial get ingress library
kubectl -n prepium-tutorial describe ingress library
The backend port is the Service port (8080), not the container port. ADDRESS may read empty or pending for a minute while the controller catches up. describe lists each host and path with its resolved backend endpoints, which catches a misspelt Service name immediately.
3. Test with a Host header
ADDR=<controller address or node IP:port>
curl -s -H "Host: books.prepium.test" http://$ADDR/healthz # ping
curl -s -H "Host: books.prepium.test" http://$ADDR/shelf/a/b # shelf
curl -s -H "Host: books.prepium.test" http://$ADDR/shelfie # no match
curl -s -H "Host: books.prepium.test" http://$ADDR/healthz/x # no match
curl -s -H "Host: maps.prepium.test" http://$ADDR/anything # atlas
Prefix matching works on whole path elements split by /: /shelf matches /shelf, /shelf/ and /shelf/a/b, but not /shelfie. Exact means exactly that string, so /healthz/x and even /healthz/ miss. Requests that match no rule are handled by the default backend, which is normally configured in the controller; check what yours returns. Without the Host header, neither rule applies, because both rules name a host.
4. Know the precedence rule
When several paths match, the longest matching path wins; on a tie, Exact beats Prefix. Add a Prefix rule for / on books.prepium.test pointing at atlas and predict, before testing, which backend answers /shelf/a, /healthz and /other.
Common mistakes
- Expecting
kubectl create ingressto produce Prefix paths. Without the*wildcard in the path, its rules default toExact, so sub-paths quietly fail. - Leaving out
ingressClassNamewhen no IngressClass is marked default. The documentation expects a default in that case; without one, whether anything serves the object depends on the controller. Set the field explicitly. - Testing by IP without a Host header. Host-specific rules do not match and you hit the default backend.
- Writing 5678, the port http-echo listens on, into
port.number. The Ingress addresses the Service, so the backend must use the Service port, 8080 here.
| Example check | Evidence |
|---|---|
| Claimed by the right controller | CLASS column matches an existing IngressClass; ADDRESS populated |
| Path semantics as intended | pathType per path in kubectl get ingress -o yaml |
| Backends resolve | describe ingress shows Service, port and endpoints for every path |
| Routing works | curl with the Host header returns the expected backend per path |
Cleanup: kubectl delete namespace prepium-tutorial. References: Ingress, kubectl create ingress. Next, try migrating to Gateway API or fixing a broken Ingress.
What this tests
Expose workloads with services and ingress, and restrict traffic with network policies. On the CKA exam, Services & Networking tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.
Practice it for real
The public description lets you study the task before signing up. Full access includes every live lab. Six selected CKA scenarios are included in Free Practice, with five shared sessions each week. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.