From ba7db02190fe28730e7d072b73be3c1bf337cce2 Mon Sep 17 00:00:00 2001 From: Paul Harkink Date: Tue, 3 Mar 2026 22:42:04 +0100 Subject: [PATCH] docs: refine workshop guidance for auth, networking, and tekton --- docs/01-argocd-bootstrap.md | 13 ++++ docs/03-metallb-ingress.md | 116 ++++++++++++++++++++-------------- docs/03b-cloudflare-tunnel.md | 41 +++++++----- docs/04-tekton-pipeline.md | 27 ++++++-- 4 files changed, 130 insertions(+), 67 deletions(-) diff --git a/docs/01-argocd-bootstrap.md b/docs/01-argocd-bootstrap.md index 833a939..5cbafa2 100644 --- a/docs/01-argocd-bootstrap.md +++ b/docs/01-argocd-bootstrap.md @@ -20,6 +20,16 @@ > De extra uitlegblokken in deze oefening leggen uit *waarom* je iets doet. > Als je al ervaring hebt met ArgoCD/GitOps, kun je die blokken gerust overslaan en alleen de stappen/snippets uitvoeren. +## Vooraf lezen (optioneel) + +In deze workshop gebruiken we **Helm** voor het eerst in **stap 1**, +waar `bootstrap.sh` ArgoCD installeert via een Helm chart. + +Wil je Helm eerst kort opfrissen: + +- Helm docs (startpunt): https://helm.sh/docs/ +- Helm quickstart: https://helm.sh/docs/intro/quickstart/ + --- ## Vereisten @@ -133,6 +143,9 @@ Gebruik credentials die read-toegang geven tot je Git-repo. Als je **GitHub** gebruikt: 1. Ga naar **Settings → Developer settings → [Personal access tokens](https://github.com/settings/tokens)** + Direct naar nieuw token: + - Fine-grained: https://github.com/settings/personal-access-tokens/new + - Classic: https://github.com/settings/tokens/new 2. Maak bij voorkeur een **fine-grained token** 3. Geef de token toegang tot jouw workshop-repo 4. Zet minimaal repository permission: diff --git a/docs/03-metallb-ingress.md b/docs/03-metallb-ingress.md index ec707e1..a2cc58e 100644 --- a/docs/03-metallb-ingress.md +++ b/docs/03-metallb-ingress.md @@ -6,7 +6,6 @@ port-forward. --- - ## Wat je leert - Waarom je MetalLB nodig hebt op een bare-metal of lokaal Kubernetes-cluster @@ -35,8 +34,8 @@ L2-modus gebruikt hij ARP — jouw laptop vraagt "wie heeft 192.168.56.200?" en **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. +**nip.io** is publieke wildcard-DNS: `iets.192.168.56.200.nip.io` resolved altijd naar `192.168.56.200`. Geen noodzaak +meer om je `/etc/hosts` aanpassen. --- @@ -48,31 +47,22 @@ 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. +> [!TIP] +> **Wat dit doet** +> - Dit is de Helm-values file voor MetalLB. +> - In deze workshop-VM kun je hem leeg laten; de standaard chart-values zijn genoeg. ```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. +> [!TIP] +> **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 @@ -96,11 +86,12 @@ spec: **`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. +> [!TIP] +> **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 @@ -141,10 +132,11 @@ spec: **`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. +> [!TIP] +> **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 @@ -177,10 +169,11 @@ spec: **`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`. +> [!TIP] +> **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: @@ -198,10 +191,11 @@ controller: **`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. +> [!TIP] +> **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 @@ -272,10 +266,11 @@ Vanuit je laptop: **`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. +> [!TIP] +> **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 @@ -313,10 +308,11 @@ Open vanuit je laptop: **http://podinfo.192.168.56.200.nip.io** 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. +> [!TIP] +> **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: @@ -340,6 +336,32 @@ Open: **http://argocd.192.168.56.200.nip.io** --- +## Extra (optioneel) — alleen bij control-plane taints + +Als `metallb-speaker` pods `Pending` blijven en je node heeft een control-plane `NoSchedule` taint, +voeg dan deze toleration toe in `manifests/networking/metallb/values.yaml`: + +```yaml +speaker: + tolerations: + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule +``` +> [!TIP] +> **Wat dit doet** +> - `tolerations` zijn alleen nodig als je cluster control-plane `NoSchedule` taints gebruikt. +> +> **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 toch 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. + +Commit en push daarna opnieuw, zodat ArgoCD MetalLB met deze values heruitrolt. + +--- + ## Verwacht resultaat | URL | App | diff --git a/docs/03b-cloudflare-tunnel.md b/docs/03b-cloudflare-tunnel.md index 3e4b29e..b59eca7 100644 --- a/docs/03b-cloudflare-tunnel.md +++ b/docs/03b-cloudflare-tunnel.md @@ -26,11 +26,17 @@ ## Vereisten - Oefening 03 afgerond (Ingress-Nginx werkt) -- Een Cloudflare account - Je repo/fork op `main` -Optioneel: -- Eigen domein in Cloudflare (alleen nodig voor **Route B** hieronder) +Optioneel (alleen nodig voor **Route A** hieronder): + +- [cloudflared](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/) op de + host _of_ vm + +Optioneel (alleen nodig voor **Route B** hieronder): + +- Een Cloudflare account +- Eigen domein in Cloudflare --- @@ -106,6 +112,7 @@ el-github-push-listener.tekton-pipelines.svc:8080 ``` Belangrijk: + - Dit werkt ook als je cluster alleen op host-only netwerk draait. - Cloudflare bereikt je cluster via de actieve tunnelverbinding, niet via je LAN-IP. @@ -130,8 +137,8 @@ In dezelfde tunnel: 1. Ga naar **Public Hostnames** 2. Voeg een hostname toe, bijvoorbeeld: - - Subdomain: `tekton-webhook` - - Domain: `` + - Subdomain: `tekton-webhook` + - Domain: `` 3. Service type: `HTTP` 4. URL: `http://el-github-push-listener.tekton-pipelines.svc.cluster.local:8080` 5. Sla op @@ -233,6 +240,7 @@ spec: ``` Vervang: + - `PLAK_HIER_JE_CLOUDFLARE_TUNNEL_TOKEN` - `JOUW_FORK_URL` @@ -277,19 +285,20 @@ Gebruik in beide gevallen **niet** meer de host-only URL met `192.168.56.200.nip ## Probleemoplossing -| Symptoom | Oplossing | -|---|---| -| cloudflared pod blijft CrashLoopBackOff | Controleer of de tunnel token klopt en niet verlopen/ingetrokken is | -| Tunnel lijkt up, maar webhook geeft 502/504 | Controleer of `el-github-push-listener` service bestaat in `tekton-pipelines` | -| Geen verkeer in Tekton na GitHub push | Controleer GitHub webhook deliveries + event type `push` + secret | -| Argo app `cloudflared` blijft `Unknown` | Controleer of `repoURL` in `apps/networking/cloudflared.yaml` naar jouw fork wijst | -| `trycloudflare.com` URL werkt eerst wel maar later niet meer | Quick tunnel is tijdelijk; start opnieuw of gebruik Route B | +| Symptoom | Oplossing | +|--------------------------------------------------------------|------------------------------------------------------------------------------------| +| cloudflared pod blijft CrashLoopBackOff | Controleer of de tunnel token klopt en niet verlopen/ingetrokken is | +| Tunnel lijkt up, maar webhook geeft 502/504 | Controleer of `el-github-push-listener` service bestaat in `tekton-pipelines` | +| Geen verkeer in Tekton na GitHub push | Controleer GitHub webhook deliveries + event type `push` + secret | +| Argo app `cloudflared` blijft `Unknown` | Controleer of `repoURL` in `apps/networking/cloudflared.yaml` naar jouw fork wijst | +| `trycloudflare.com` URL werkt eerst wel maar later niet meer | Quick tunnel is tijdelijk; start opnieuw of gebruik Route B | --- ## Security-opmerking Gebruik in een echte omgeving liever: + - externe secret manager voor tunnel token - aparte Cloudflare tunnel per omgeving - least-privilege Cloudflare account/API instellingen @@ -304,7 +313,7 @@ Wil je een voorbeeld zien zonder alles handmatig te typen? - Branch: `solution/03b-cloudflare-tunnel` - Daarin staan: - - `apps/networking/cloudflared.yaml` - - `manifests/networking/cloudflared/namespace.yaml` - - `manifests/networking/cloudflared/token.secret.yaml` (placeholder token) - - `manifests/networking/cloudflared/deployment.yaml` + - `apps/networking/cloudflared.yaml` + - `manifests/networking/cloudflared/namespace.yaml` + - `manifests/networking/cloudflared/token.secret.yaml` (placeholder token) + - `manifests/networking/cloudflared/deployment.yaml` diff --git a/docs/04-tekton-pipeline.md b/docs/04-tekton-pipeline.md index fb68dec..9204d30 100644 --- a/docs/04-tekton-pipeline.md +++ b/docs/04-tekton-pipeline.md @@ -21,6 +21,18 @@ volledige GitOps CI/CD-loop. > Alle alinea's met "Waarom dit" kun je zien als mini-achtergrond. > Gevorderden kunnen die overslaan en direct de snippets volgen. +## Vooraf lezen (optioneel) + +Als Tekton nieuw voor je is, skim eerst deze pagina's: + +- Tekton docs (startpunt): https://tekton.dev/docs/ +- Core concepten (Tasks, Pipelines, PipelineRuns): https://tekton.dev/docs/pipelines/ +- Eerste voorbeeldpipeline: https://tekton.dev/docs/getting-started/pipelines/ +- Kustomize docs (startpunt): https://kubectl.docs.kubernetes.io/references/kustomize/ + +In deze workshop gebruiken we **Kustomize** voor het eerst in **stap 1** +met `manifests/ci/tekton/kustomization.yaml`. + --- ## De loop @@ -53,6 +65,9 @@ Oefeningen 01–03 afgerond. podinfo is bereikbaar via **http://podinfo.192.168. Je hebt nodig: - Een GitHub Personal Access Token (PAT) met **repo**-scope (lezen + schrijven) + Maak er direct een aan via: + - Fine-grained: https://github.com/settings/personal-access-tokens/new + - Classic: https://github.com/settings/tokens/new --- @@ -76,8 +91,8 @@ Waarom dit: - `release.yaml` installeert Tekton Pipelines (controller, webhook, CRDs). - De `patches` regel past de namespace aan die al in de upstream release zit. -- Zonder patch faalt de eerste TaskRun vaak op Pod Security admission. -- Pod Security Admission is een Kubernetes-mechanisme dat per namespace bepaalt hoe streng pod-beveiliging wordt +- Zonder patch faalt de eerste TaskRun vaak op Pod Security Admission (PSA). +- Pod Security Admission (PSA) is een Kubernetes-mechanisme dat per namespace bepaalt hoe streng pod-beveiliging wordt afgedwongen. - In deze oefening zet de upstream Tekton install de namespace effectief op `restricted`; dat profiel eist o.a. `runAsNonRoot`, `seccompProfile` en `allowPrivilegeEscalation=false`. @@ -176,7 +191,7 @@ Waarom dit: - Alle permissies voor `validate` en eventuele cluster-calls hangen aan dit account. **`manifests/ci/pipeline/pipeline.yaml`** — zie de solution branch voor de volledige inhoud, of kopieer uit -`reference-solution`: +`reference-solution`: > **HOST** > ```bash @@ -356,7 +371,11 @@ Dit is een verplichte stap vóór je de PipelineRun triggert. Zonder `git-credentials` secret faalt de `clone` task direct. De pipeline moet kunnen pushen naar jouw fork. -Maak een GitHub PAT aan met `repo`-scope en voer daarna een van deze opties uit: +Maak een GitHub PAT aan met `repo`-scope en voer daarna een van deze opties uit. +Direct links: + +- Fine-grained token: https://github.com/settings/personal-access-tokens/new +- Classic token: https://github.com/settings/tokens/new > **VM** > ```bash