Add ingress-nginx
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
# ingress-nginx, installed like MetalLB and Longhorn: an Application
|
||||||
|
# pointing at apps/ingress-nginx, a Helm chart that pulls in the upstream
|
||||||
|
# ingress-nginx chart. Once this syncs, apps can request a hostname-routed
|
||||||
|
# address via an Ingress resource instead of each needing its own MetalLB
|
||||||
|
# LoadBalancer Service. See docs/11-ingress.md.
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: ingress-nginx
|
||||||
|
namespace: argocd
|
||||||
|
# Safe to cascade: ingress-nginx holds no persistent data of its own,
|
||||||
|
# unlike apps/longhorn.yaml.
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
|
||||||
|
source:
|
||||||
|
repoURL: https://tea.ahmza.com/ahmza/k8s-starter-pack.git
|
||||||
|
targetRevision: main
|
||||||
|
path: apps/ingress-nginx
|
||||||
|
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: ingress-nginx
|
||||||
|
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# An "umbrella" chart, same pattern as apps/metallb/ and apps/longhorn/:
|
||||||
|
# declares a dependency on the upstream ingress-nginx chart. Argo CD detects
|
||||||
|
# this as a Helm source because a Chart.yaml exists at this path.
|
||||||
|
#
|
||||||
|
# See docs/11-ingress.md for why this exists: one shared LoadBalancer
|
||||||
|
# address routing many hostnames, instead of every app needing its own
|
||||||
|
# MetalLB address.
|
||||||
|
apiVersion: v2
|
||||||
|
name: ingress-nginx-app
|
||||||
|
description: Installs ingress-nginx, routing many hostnames through one shared LoadBalancer address
|
||||||
|
version: 0.1.0
|
||||||
|
dependencies:
|
||||||
|
- name: ingress-nginx
|
||||||
|
# A version range rather than an exact pin, so this doesn't silently go
|
||||||
|
# stale. Check https://artifacthub.io/packages/helm/ingress-nginx/ingress-nginx
|
||||||
|
# for the current release and pin an exact version for a fully
|
||||||
|
# reproducible install.
|
||||||
|
version: ">=4.11.0"
|
||||||
|
repository: https://kubernetes.github.io/ingress-nginx
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Values for the upstream ingress-nginx chart, nested under
|
||||||
|
# `ingress-nginx:` (the dependency's name in Chart.yaml).
|
||||||
|
ingress-nginx:
|
||||||
|
controller:
|
||||||
|
service:
|
||||||
|
type: LoadBalancer
|
||||||
|
annotations:
|
||||||
|
# Requests this specific address from MetalLB's BGP pool (see
|
||||||
|
# docs/05-metallb.md) so it stays predictable across rebuilds.
|
||||||
|
# Must fall inside apps/metallb/templates/ipaddresspool.yaml's
|
||||||
|
# range, or MetalLB will never satisfy the request.
|
||||||
|
metallb.io/loadBalancerIPs: "10.10.60.12"
|
||||||
|
# ingress-nginx's default Pod Security posture (no hostNetwork, no
|
||||||
|
# hostPath, only the baseline-allowed NET_BIND_SERVICE capability to
|
||||||
|
# bind ports 80/443) already fits Kubernetes' baseline profile, unlike
|
||||||
|
# MetalLB or Longhorn. No managedNamespaceMetadata override needed here.
|
||||||
|
ingressClassResource:
|
||||||
|
# Every Ingress resource in this cluster that doesn't name a class
|
||||||
|
# explicitly uses this one automatically \u2014 the same "no
|
||||||
|
# storageClassName needed" convenience Longhorn gives PVCs.
|
||||||
|
default: true
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# 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.
|
||||||
+4
-1
@@ -50,7 +50,7 @@ This dedicated service range is advertised to the MikroTik at
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| `10.10.60.10` | Argo CD UI/API (`argocd-server`) | `argocd` | 443 | `https://10.10.60.10` | Patched to `LoadBalancer` by hand — see [`docs/05-metallb.md`](05-metallb.md) |
|
| `10.10.60.10` | Argo CD UI/API (`argocd-server`) | `argocd` | 443 | `https://10.10.60.10` | Patched to `LoadBalancer` by hand — see [`docs/05-metallb.md`](05-metallb.md) |
|
||||||
| `10.10.60.11` | Demo app | `demo` | 80 | `http://10.10.60.11` | [`apps/demo/service.yaml`](../apps/demo/service.yaml) |
|
| `10.10.60.11` | Demo app | `demo` | 80 | `http://10.10.60.11` | [`apps/demo/service.yaml`](../apps/demo/service.yaml) |
|
||||||
| `10.10.60.12` | whoami app | `whoami` | 80 | `http://10.10.60.12` | [`apps/whoami/service.yaml`](../apps/whoami/service.yaml) |
|
| `10.10.60.12` | ingress-nginx (shared, routes by hostname) | `ingress-nginx` | 80, 443 | `http://10.10.60.12`, `https://10.10.60.12` | [`apps/ingress-nginx/values.yaml`](../apps/ingress-nginx/values.yaml) — see [`docs/11-ingress.md`](11-ingress.md) |
|
||||||
|
|
||||||
Add a row here every time you add a new app with a `LoadBalancer` Service
|
Add a row here every time you add a new app with a `LoadBalancer` Service
|
||||||
(see [`docs/08-adding-new-apps.md`](08-adding-new-apps.md)). Leave the URL
|
(see [`docs/08-adding-new-apps.md`](08-adding-new-apps.md)). Leave the URL
|
||||||
@@ -64,3 +64,6 @@ alongside the table above so it's obvious at a glance what's safe to hand
|
|||||||
to the next app.
|
to the next app.
|
||||||
|
|
||||||
- `10.10.60.13-10.10.60.250`
|
- `10.10.60.13-10.10.60.250`
|
||||||
|
|
||||||
|
(`whoami`'s former `10.10.60.12` was reclaimed here after that app was
|
||||||
|
removed as the docs/08 exercise — it now belongs to ingress-nginx instead.)
|
||||||
|
|||||||
Reference in New Issue
Block a user