Ingress — Full Reference¶
Reference: https://kubernetes.io/docs/concepts/services-networking/ingress/
Exam Priority — Quickest Path¶
No imperative command for Ingress — always YAML. Generate a scaffold from docs or dry-run an existing resource:
# Get the template from the docs page:
# kubernetes.io/docs/concepts/services-networking/ingress → Ctrl+F "pathType"
# Or copy an existing ingress as a starting point:
kubectl get ingress <name> -o yaml > ingress.yaml
The minimum YAML you need (memorise this structure):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /shop
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
What Is Ingress and Why It Exists¶
You have services running inside the cluster. ClusterIP = internal only. NodePort = one port per service on every node, messy. LoadBalancer = needs a cloud provider.
Ingress is a single entry point that routes external HTTP/HTTPS traffic to different services based on rules.
External traffic
↓
Ingress (one IP, one entry point)
↓
/api → api-service:80
/web → web-service:80
/shop → shop-service:80
Without Ingress: 3 services = 3 NodePorts = 3 different ports to manage, document, and secure. With Ingress: one entry point, routing rules decide where traffic goes.
Three separate things — all required:
| Thing | What it is | Required? |
|---|---|---|
| Ingress resource | The YAML you write. Just routing rules. Does nothing on its own. | Yes |
| Ingress controller | The actual software (nginx, traefik, etc.) that reads the rules and does the routing. Must be installed separately. | Yes |
| Service | Ingress routes TO a Service, not directly to pods. | Yes |
Creating an Ingress resource without an Ingress controller installed = nothing happens. The resource gets created, kubectl apply succeeds, but no traffic gets routed.
Ingress Resource — Full YAML¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-resource
namespace: default
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false" # disable HTTPS redirect
nginx.ingress.kubernetes.io/rewrite-target: / # rewrite path before forwarding
spec:
ingressClassName: nginx # which ingress controller handles this — MUST match
rules:
- host: myapp.example.com # optional — only route this hostname (omit for all traffic)
http:
paths:
- path: /shop
pathType: Prefix # Prefix | Exact | ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 80
tls: # optional — TLS termination
- hosts:
- myapp.example.com
secretName: my-tls-secret # Secret with tls.crt and tls.key
ingressClassName — The #1 Mistake¶
# WRONG — this is YOUR resource name, not the controller class
ingressClassName: nginx-ingress-resource
# CORRECT — must match the installed controller's class name
ingressClassName: nginx
ingressClassName tells the Ingress controller "hey, you're responsible for this resource." If it doesn't match, the controller ignores your Ingress completely.
Find what's installed:
Output:Use nginx (or whatever name is shown) as your ingressClassName.
KillerCoda vs real cluster: KillerCoda's checker validates that your Ingress YAML has the right spec fields. It doesn't test actual traffic routing. So even with the wrong ingressClassName, you might pass the KillerCoda check — but in a real cluster, traffic would never route.
pathType — Three Options¶
| pathType | Behaviour |
|---|---|
Prefix |
Matches the path and anything under it. /shop matches /shop, /shop/, /shop/products |
Exact |
Matches only the exact path. /shop matches /shop only, not /shop/ |
ImplementationSpecific |
Behaviour depends on the Ingress controller |
For the exam: Prefix is the most common. Use Exact when the question specifies it.
Annotations¶
Annotations are how you configure Ingress controller-specific behaviour. They live in metadata.annotations.
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false" # disable HTTP→HTTPS redirect
nginx.ingress.kubernetes.io/rewrite-target: / # rewrite path to / before forwarding
nginx.ingress.kubernetes.io/proxy-body-size: "10m" # max request body size
nginx.ingress.kubernetes.io/proxy-read-timeout: "60" # timeout in seconds
Why strings for booleans? "false" not false. All annotation values are strings in Kubernetes. Even booleans must be quoted.
Routing Patterns¶
Single service (no host, no path matching)¶
All traffic →my-service.
Path-based fanout (one host, multiple services)¶
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Host-based routing (multiple hostnames)¶
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
TLS termination¶
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: my-tls-secret # kubectl create secret tls my-tls-secret --cert=... --key=...
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
The Exercise — Full Solution¶
Create
nginx-ingress-resource: pathType Prefix, path /shop, backend servicenginx-serviceport 80, ssl-redirect false.
# 1. Check what ingress controller class is installed
kubectl get ingressclass
# 2. Create the YAML
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-resource
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /shop
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
EOF
# 3. Verify
kubectl get ingress nginx-ingress-resource
kubectl describe ingress nginx-ingress-resource
Inspecting Ingress¶
kubectl get ingress
kubectl get ingress -A # all namespaces
kubectl describe ingress my-ingress # rules, backend, events
kubectl get ingressclass # what controllers are installed
kubectl describe ingress shows you the full routing table and any events (like the controller ignoring it due to wrong ingressClassName).
Docs Bookmark¶
URL: kubernetes.io/docs/concepts/services-networking/ingress
Ctrl+F for: pathType — takes you straight to the fanout example YAML. Copy it, edit 4-5 fields, apply.
Quick Reference¶
# No imperative command — always YAML
kubectl apply -f ingress.yaml
kubectl get ingress
kubectl describe ingress <name>
kubectl get ingressclass # find correct ingressClassName value
kubectl delete ingress <name>
# Generate from existing
kubectl get ingress <name> -o yaml > ingress.yaml
Minimum fields checklist:
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata.name
- spec.ingressClassName ← must match kubectl get ingressclass output
- spec.rules[].http.paths[].path
- spec.rules[].http.paths[].pathType
- spec.rules[].http.paths[].backend.service.name
- spec.rules[].http.paths[].backend.service.port.number