84 lines
3.4 KiB
Markdown
84 lines
3.4 KiB
Markdown
# 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`](../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`](../apps/ingress-nginx/values.yaml) gives
|
||
|
|
its Service a fixed address from the MetalLB pool
|
||
|
|
(`10.10.60.12` — see [`docs/network.md`](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
|
||
|
|
|
||
|
|
```sh
|
||
|
|
argocd app get ingress-nginx
|
||
|
|
```
|
||
|
|
|
||
|
|
```sh
|
||
|
|
kubectl -n ingress-nginx get svc
|
||
|
|
```
|
||
|
|
|
||
|
|
`EXTERNAL-IP` should show `10.10.60.12`.
|
||
|
|
|
||
|
|
```sh
|
||
|
|
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:
|
||
|
|
|
||
|
|
1. Change its Service from `type: LoadBalancer` back to the implicit
|
||
|
|
default, `ClusterIP` — it no longer needs its own address.
|
||
|
|
2. Add an `Ingress` resource naming a real hostname and pointing at that
|
||
|
|
Service.
|
||
|
|
3. 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-nginx` Application `Synced`/`Healthy`
|
||
|
|
- [ ] `kubectl -n ingress-nginx get svc` shows `EXTERNAL-IP` `10.10.60.12`
|
||
|
|
- [ ] `kubectl get ingressclass` shows 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`](12-cert-manager.md) for real HTTPS
|
||
|
|
certificates on that hostname.
|