357 lines
9.8 KiB
Markdown
357 lines
9.8 KiB
Markdown
# Oefening 03 — MetalLB + Ingress-Nginx
|
|
|
|
**Tijd**: ~45 minuten
|
|
**Doel**: podinfo en de ArgoCD UI bereikbaar maken op een echt LAN-IP — vanuit je browser op je laptop, zonder
|
|
port-forward.
|
|
|
|
---
|
|
|
|
|
|
## Wat je leert
|
|
|
|
- Waarom je MetalLB nodig hebt op een bare-metal of lokaal Kubernetes-cluster
|
|
- Hoe een LoadBalancer-service een echt IP krijgt via L2 ARP
|
|
- Hoe Ingress-Nginx HTTP-verkeer routeert op basis van hostname
|
|
- nip.io: gratis wildcard-DNS voor lokale development
|
|
|
|
---
|
|
|
|
## Achtergrond
|
|
|
|
In cloud-Kubernetes (EKS, GKE, AKS) regelt `type: LoadBalancer` automatisch een load balancer met een extern IP. Op bare
|
|
metal of lokale VMs doet niets dat — pods blijven onbereikbaar van buitenaf.
|
|
|
|
**MetalLB** lost dit op: hij luistert naar LoadBalancer-services en kent IPs toe uit een pool die jij definieert. In
|
|
L2-modus gebruikt hij ARP — jouw laptop vraagt "wie heeft 192.168.56.200?" en MetalLB antwoordt namens de VM.
|
|
|
|
**Ingress-Nginx** is één LoadBalancer-service die van MetalLB één IP krijgt. Al je apps delen dat IP — Nginx routeert op
|
|
basis van de `Host:` header.
|
|
|
|
**nip.io** is publieke wildcard-DNS: `iets.192.168.56.200.nip.io` resolvet altijd naar `192.168.56.200`. Geen
|
|
`/etc/hosts` aanpassen.
|
|
|
|
---
|
|
|
|
## Stappen
|
|
|
|
### 1. MetalLB installeren
|
|
|
|
Maak de volgende bestanden aan:
|
|
|
|
**`manifests/networking/metallb/values.yaml`**
|
|
|
|
Wat dit doet:
|
|
- Configureert de MetalLB speaker pod.
|
|
- Met deze `toleration` mag de speaker op de control-plane node draaien.
|
|
- Dat is nodig in deze workshop, omdat je VM meestal maar 1 node heeft.
|
|
|
|
Termen uitgelegd:
|
|
- `speaker`: de MetalLB component die op nodes draait en op het netwerk "antwoordt" voor een toegewezen
|
|
LoadBalancer-IP (in L2-modus via ARP).
|
|
- `tolerations`: een Kubernetes-mechanisme waarmee een pod tóch op een node mag landen die een `taint` heeft.
|
|
Control-plane nodes zijn vaak getaint met `NoSchedule`; zonder toleration wordt de speaker daar niet ingepland.
|
|
|
|
```yaml
|
|
speaker:
|
|
tolerations:
|
|
- key: node-role.kubernetes.io/control-plane
|
|
operator: Exists
|
|
effect: NoSchedule
|
|
```
|
|
|
|
**`manifests/networking/metallb/metallb-config.yaml`**
|
|
|
|
Wat dit doet:
|
|
- `IPAddressPool` bepaalt uit welke range MetalLB IP's mag uitdelen.
|
|
- `L2Advertisement` maakt die pool zichtbaar op je host-only netwerk via ARP.
|
|
- Daardoor kan je laptop services op dat IP direct bereiken.
|
|
|
|
```yaml
|
|
apiVersion: metallb.io/v1beta1
|
|
kind: IPAddressPool
|
|
metadata:
|
|
name: workshop-pool
|
|
namespace: metallb-system
|
|
spec:
|
|
addresses:
|
|
- 192.168.56.200-192.168.56.220
|
|
---
|
|
apiVersion: metallb.io/v1beta1
|
|
kind: L2Advertisement
|
|
metadata:
|
|
name: workshop-l2
|
|
namespace: metallb-system
|
|
spec:
|
|
ipAddressPools:
|
|
- workshop-pool
|
|
```
|
|
|
|
**`apps/networking/metallb.yaml`**
|
|
|
|
Wat dit doet:
|
|
- Installeert MetalLB via ArgoCD als aparte `Application`.
|
|
- De chart komt van de upstream Helm repo; jouw repo levert de values via `$values/...`.
|
|
- `sync-wave: "1"` zorgt dat MetalLB eerst klaar is.
|
|
- `ignoreDifferences` voorkomt bekende CRD `caBundle` drift door dynamische webhook certs.
|
|
|
|
```yaml
|
|
apiVersion: argoproj.io/v1alpha1
|
|
kind: Application
|
|
metadata:
|
|
name: metallb
|
|
namespace: argocd
|
|
annotations:
|
|
argocd.argoproj.io/sync-wave: "1"
|
|
spec:
|
|
project: workshop
|
|
ignoreDifferences:
|
|
- group: apiextensions.k8s.io
|
|
kind: CustomResourceDefinition
|
|
jsonPointers:
|
|
- /spec/conversion/webhook/clientConfig/caBundle
|
|
sources:
|
|
- repoURL: https://metallb.github.io/metallb
|
|
chart: metallb
|
|
targetRevision: "0.14.9"
|
|
helm:
|
|
valueFiles:
|
|
- $values/manifests/networking/metallb/values.yaml
|
|
- repoURL: JOUW_FORK_URL
|
|
targetRevision: HEAD
|
|
ref: values
|
|
destination:
|
|
server: https://kubernetes.default.svc
|
|
namespace: metallb-system
|
|
syncPolicy:
|
|
automated:
|
|
prune: true
|
|
selfHeal: true
|
|
syncOptions:
|
|
- CreateNamespace=true
|
|
- ServerSideApply=true
|
|
```
|
|
|
|
**`apps/networking/metallb-config.yaml`**
|
|
|
|
Wat dit doet:
|
|
- Past jouw IP-pool/L2-config toe als losse ArgoCD `Application`.
|
|
- Die split houdt "installatie" en "runtime-config" van MetalLB uit elkaar.
|
|
- `sync-wave: "2"` laat dit pas lopen nadat MetalLB zelf staat.
|
|
|
|
```yaml
|
|
apiVersion: argoproj.io/v1alpha1
|
|
kind: Application
|
|
metadata:
|
|
name: metallb-config
|
|
namespace: argocd
|
|
annotations:
|
|
argocd.argoproj.io/sync-wave: "2"
|
|
spec:
|
|
project: workshop
|
|
source:
|
|
repoURL: JOUW_FORK_URL
|
|
targetRevision: HEAD
|
|
path: manifests/networking/metallb
|
|
directory:
|
|
include: "metallb-config.yaml"
|
|
destination:
|
|
server: https://kubernetes.default.svc
|
|
namespace: metallb-system
|
|
syncPolicy:
|
|
automated:
|
|
prune: true
|
|
selfHeal: true
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Ingress-Nginx installeren
|
|
|
|
**`manifests/networking/ingress-nginx/values.yaml`**
|
|
|
|
Wat dit doet:
|
|
- Zet ingress-nginx neer met een `LoadBalancer` service.
|
|
- Dat service-IP wordt vast op `192.168.56.200` gezet.
|
|
- Zo kun je stabiele hostnames gebruiken met `nip.io`.
|
|
|
|
```yaml
|
|
controller:
|
|
ingressClassResource:
|
|
name: nginx
|
|
default: true
|
|
service:
|
|
type: LoadBalancer
|
|
loadBalancerIP: "192.168.56.200"
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 128Mi
|
|
```
|
|
|
|
**`apps/networking/ingress-nginx.yaml`**
|
|
|
|
Wat dit doet:
|
|
- Installeert ingress-nginx via ArgoCD.
|
|
- Ook hier: chart upstream, values uit jouw repo.
|
|
- `sync-wave: "3"` laat ingress pas starten nadat MetalLB + config klaar zijn.
|
|
|
|
```yaml
|
|
apiVersion: argoproj.io/v1alpha1
|
|
kind: Application
|
|
metadata:
|
|
name: ingress-nginx
|
|
namespace: argocd
|
|
annotations:
|
|
argocd.argoproj.io/sync-wave: "3"
|
|
spec:
|
|
project: workshop
|
|
sources:
|
|
- repoURL: https://kubernetes.github.io/ingress-nginx
|
|
chart: ingress-nginx
|
|
targetRevision: "4.12.0"
|
|
helm:
|
|
valueFiles:
|
|
- $values/manifests/networking/ingress-nginx/values.yaml
|
|
- repoURL: JOUW_FORK_URL
|
|
targetRevision: HEAD
|
|
ref: values
|
|
destination:
|
|
server: https://kubernetes.default.svc
|
|
namespace: ingress-nginx
|
|
syncPolicy:
|
|
automated:
|
|
prune: true
|
|
selfHeal: true
|
|
syncOptions:
|
|
- CreateNamespace=true
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Alles committen en pushen
|
|
|
|
> **HOST**
|
|
> ```bash
|
|
> git add apps/networking/ manifests/networking/
|
|
> git commit -m "feat: MetalLB + Ingress-Nginx"
|
|
> git push
|
|
> ```
|
|
|
|
Wacht tot beide applications Synced zijn, en controleer dan:
|
|
|
|
> **VM**
|
|
> ```bash
|
|
> kubectl get svc -n ingress-nginx
|
|
> # NAME TYPE EXTERNAL-IP PORT(S)
|
|
> # ingress-nginx-controller LoadBalancer 192.168.56.200 80:xxx,443:xxx
|
|
> ```
|
|
|
|
Vanuit je laptop:
|
|
|
|
> **HOST**
|
|
> ```bash
|
|
> curl http://192.168.56.200
|
|
> # 404 van Nginx — klopt, nog geen Ingress-regel
|
|
> ```
|
|
|
|
---
|
|
|
|
### 4. Ingress voor podinfo toevoegen
|
|
|
|
**`manifests/apps/podinfo/ingress.yaml`**
|
|
|
|
Wat dit doet:
|
|
- Definieert de HTTP-route voor podinfo.
|
|
- `ingressClassName: nginx` bindt deze Ingress aan ingress-nginx.
|
|
- De hostnaam met `nip.io` wijst naar jouw MetalLB IP.
|
|
|
|
```yaml
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: podinfo
|
|
namespace: podinfo
|
|
spec:
|
|
ingressClassName: nginx
|
|
rules:
|
|
- host: podinfo.192.168.56.200.nip.io
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: podinfo
|
|
port:
|
|
name: http
|
|
```
|
|
|
|
> **HOST**
|
|
> ```bash
|
|
> git add manifests/apps/podinfo/ingress.yaml
|
|
> git commit -m "feat: voeg podinfo Ingress toe"
|
|
> git push
|
|
> ```
|
|
|
|
Open vanuit je laptop: **http://podinfo.192.168.56.200.nip.io**
|
|
|
|
---
|
|
|
|
### 5. ArgoCD-ingress inschakelen
|
|
|
|
Pas `manifests/argocd/values.yaml` aan. Zoek het uitgecommentarieerde ingress-blok en verwijder de `#`-tekens:
|
|
|
|
Wat dit doet:
|
|
- Schakelt ingress in voor de ArgoCD server zelf.
|
|
- Daarna kun je ArgoCD via browser-URL gebruiken in plaats van port-forward.
|
|
- De `hostname` moet matchen met het IP dat ingress-nginx exposeert.
|
|
|
|
```yaml
|
|
ingress:
|
|
enabled: true
|
|
ingressClassName: nginx
|
|
hostname: argocd.192.168.56.200.nip.io
|
|
annotations:
|
|
nginx.ingress.kubernetes.io/ssl-passthrough: "false"
|
|
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
|
```
|
|
|
|
> **HOST**
|
|
> ```bash
|
|
> git add manifests/argocd/values.yaml
|
|
> git commit -m "feat: schakel ArgoCD ingress in"
|
|
> git push
|
|
> ```
|
|
|
|
ArgoCD detecteert de wijziging, past zijn eigen Helm-release aan en maakt de Ingress aan.
|
|
Open: **http://argocd.192.168.56.200.nip.io**
|
|
|
|
---
|
|
|
|
## Verwacht resultaat
|
|
|
|
| URL | App |
|
|
|--------------------------------------|----------------|
|
|
| http://podinfo.192.168.56.200.nip.io | podinfo v6.6.2 |
|
|
| http://argocd.192.168.56.200.nip.io | ArgoCD UI |
|
|
|
|
Beide bereikbaar vanaf je laptop zonder port-forward.
|
|
|
|
---
|
|
|
|
## Probleemoplossing
|
|
|
|
| Symptoom | Oplossing |
|
|
|---------------------------------------|--------------------------------------------------------------------------------------------------------------------|
|
|
| `EXTERNAL-IP` blijft `<pending>` | MetalLB is nog niet klaar — check `kubectl get pods -n metallb-system` |
|
|
| curl naar 192.168.56.200 time-out | VirtualBox host-only adapter niet geconfigureerd — zie vm-setup.md |
|
|
| nip.io resolvet niet | Tijdelijk DNS-probleem, probeer opnieuw of voeg toe aan `/etc/hosts` |
|
|
| ArgoCD ingress geeft 502 | Wacht tot ArgoCD herstart na de values-wijziging |
|
|
| MetalLB app blijft OutOfSync op CRD's | Voeg in `apps/networking/metallb.yaml` `ignoreDifferences` toe voor CRD `caBundle` drift (zie voorbeeld hierboven) |
|
|
|
|
---
|
|
|
|
## Volgende stap
|
|
|
|
In Oefening 04 bouw je een Tekton-pipeline die automatisch de image-tag in Git aanpast, pusht, en laat ArgoCD de update
|
|
uitrollen.
|