Ingress Basics
This section introduces the Ingress object: how to route external HTTP traffic to in-cluster Services by host and path, with TLS.
Remember that an Ingress is just declarative configuration. A running ingress controller must be installed for any of these examples to take effect.
Prerequisites
- Kubernetes 1.36.2 cluster with
kubectlaccess. - An ingress controller installed (for example ingress-nginx). Ingress objects do nothing without one.
- A Service in front of your workload pods.
- Optional: a real DNS name pointing at the controller's external IP for live testing.
Quick install of a common controller with Helm 3:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespaceBasic Examples
1. A single host to one Service
Route all traffic for a hostname to one backend Service.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80ingressClassNamebinds the object to a specific installed controller.pathType: Prefixmatches/and everything under it.- The
backendnames a Service and its port, not a pod. - The Service must already exist and select healthy pods.
2. Path-based routing (fanout)
Send different URL paths to different Services behind one host.
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80- List more specific paths first; controllers match by longest prefix.
- Each path targets its own Service.
/apigoes to the api Service, everything else to web.
3. Name-based virtual hosting
Serve multiple hostnames from one Ingress and one controller.
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: web, port: { number: 80 } } }
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: admin, port: { number: 80 } } }- Each
hostblock is an independent virtual host. - The controller routes on the HTTP
Hostheader. - Both names resolve to the same controller IP in DNS.
4. pathType exact match
Match a single URL exactly, not its subtree.
- path: /healthz
pathType: Exact
backend:
service:
name: web
port:
number: 80Exactmatches only/healthz, not/healthz/extra.- Use it for well-known single endpoints.
Prefixis the more common choice for app routes.
5. A default backend
Catch requests that match no rule.
spec:
ingressClassName: nginx
defaultBackend:
service:
name: fallback
port:
number: 80- Unmatched hosts or paths go to
defaultBackend. - Useful for a friendly 404 page or a maintenance Service.
- Without it, the controller returns its own default response.
6. Basic TLS termination
Terminate HTTPS at the controller using a Secret.
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: web, port: { number: 80 } } }- The
tlsblock references akubernetes.io/tlsSecret holding the cert and key. - The
hostslist should match the SNI names in the certificate. - The controller decrypts and forwards plaintext to the pod.
7. Referencing an IngressClass explicitly
Confirm which controller owns your objects.
kubectl get ingressclass- Each controller registers an
IngressClass(for examplenginx). spec.ingressClassNamemust match one of these.- One class can be marked default for objects that omit the field.
Intermediate Examples
8. Controller-specific annotations
Enable features not covered by the core spec via annotations.
metadata:
name: web
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"- Annotations are read only by the named controller.
ssl-redirectforces HTTP to HTTPS.proxy-body-sizeraises the upload limit.- Annotation keys differ per controller, so they are not portable.
9. Rewriting paths
Strip a prefix before forwarding to the backend.
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend: { service: { name: api, port: { number: 8080 } } }rewrite-targetrewrites the forwarded path using capture groups.pathType: ImplementationSpecificallows regex in ingress-nginx.- The backend receives
/instead of/api.
10. Multiple hosts on one TLS block
Serve several hostnames over HTTPS using one certificate with Subject Alternative Names.
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
- admin.example.com
secretName: multi-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: web, port: { number: 80 } } }
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: admin, port: { number: 80 } } }- One TLS Secret can cover multiple names if the certificate lists them as SANs.
- Each
hoststill needs its own rule block for routing. - The controller selects the certificate by SNI at the TLS handshake.
11. Verifying the live route
Test without changing DNS by sending an explicit Host header.
kubectl get ingress web
curl -H "Host: app.example.com" http://<controller-external-ip>/kubectl get ingressshows the assigned address once the controller reconciles.- The
Hostheader makes the controller match your rule. - A 502 usually means the Service has no ready endpoints.
- Add
-kto skip cert verification when testing HTTPS against an IP.
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).