3.4 KiB
11 — Ingress: many hostnames, one address
So far, every app that needs to be reachable gets its own dedicated
address from MetalLB's BGP pool (docs/05-metallb.md) — Argo CD at
10.10.60.10, the demo app at 10.10.60.11. That's fine for a handful of
apps, but doesn't scale: every app eats another address out of a pool
that's only so big, and there's no way to route by hostname
(blog.ahmza.com vs photos.ahmza.com sharing one address on port 443).
What Ingress actually is
An Ingress controller is a reverse proxy that sits behind one
MetalLB address and reads Ingress resources — small manifests that say
"requests for this hostname go to that Service." Instead of every app
declaring its own type: LoadBalancer Service, most apps go back to a
plain internal ClusterIP Service, and get an Ingress resource pointing
at it. One address, many hostnames.
ingress-nginx is the controller this cluster uses — the most common,
most documented choice, distributed as a Helm chart just like MetalLB and
Longhorn (see apps/ingress-nginx/Chart.yaml).
What's already running
apps/ingress-nginx.yaml → one Application, pointing at
apps/ingress-nginx, pulling in the upstream chart.
apps/ingress-nginx/values.yaml gives
its Service a fixed address from the MetalLB pool
(10.10.60.12 — see docs/network.md) and marks its
IngressClass as the cluster default, so an Ingress resource that
doesn't name a class explicitly still uses it — the same convenience
Longhorn gives PVCs that don't name a storageClassName.
Unlike MetalLB and Longhorn, ingress-nginx needed no Pod Security
exemption: it only needs the NET_BIND_SERVICE capability to bind ports
80/443, which Kubernetes' baseline profile already permits (unlike
hostNetwork or hostPath, which it forbids).
Verify it's actually running
argocd app get ingress-nginx
kubectl -n ingress-nginx get svc
EXTERNAL-IP should show 10.10.60.12.
kubectl get ingressclass
Should show one IngressClass, marked as the default via annotation.
Routing a real app through it
Converting an app from its own MetalLB address to Ingress means:
- Change its Service from
type: LoadBalancerback to the implicit default,ClusterIP— it no longer needs its own address. - Add an
Ingressresource naming a real hostname and pointing at that Service. - Point that hostname at ingress-nginx's address,
10.10.60.12— either a real DNS record (safe even for a LAN-only cluster: a public DNS record pointing at a private address just won't resolve to anything reachable from outside your LAN yet, which is fine until you actually expose this cluster publicly) or a local override for testing.
This is exactly what docs/12-cert-manager.md builds on next — a real
hostname is what a TLS certificate actually gets issued for.
Checklist
ingress-nginxApplicationSynced/Healthykubectl -n ingress-nginx get svcshowsEXTERNAL-IP10.10.60.12kubectl get ingressclassshows the default class- (Optional, hands-on) Converted one app to route through Ingress with a real hostname instead of its own MetalLB address
Continue to docs/12-cert-manager.md for real HTTPS
certificates on that hostname.