docs: refresh workshop talks and add intro slides

This commit is contained in:
Paul Harkink 2026-03-03 23:40:52 +01:00
parent 5177726cfa
commit 6683d13f0a
4 changed files with 317 additions and 122 deletions

View file

@ -1,150 +1,90 @@
# Final Talk GitOps in de praktijk
# Final Talk - GitOps in de praktijk
---
## 1. Wat we nu echt hebben staan
## 1. Wat we gebouwd hebben
Vandaag hebben we niet "een demo" gebouwd, maar een complete GitOps-loop:
### Architectuurdiagram
1. Git bevat de gewenste state.
2. ArgoCD reconcilet de cluster daarnaar.
3. Tekton wijzigt Git (image-tag bump), en ArgoCD pakt dat weer op.
4. Alles is reproduceerbaar op een nieuwe VM.
### Snelle architectuur
```
┌─────────────────────────────────────────────────────────┐
│ Jouw laptop │
│ │
│ Browser ──────────────────────────────────────────► │
│ podinfo.192.168.56.200.nip.io │
│ argocd.192.168.56.200.nip.io │
│ grafana.192.168.56.200.nip.io │
└────────────────────────┬────────────────────────────────┘
│ VirtualBox host-only
▼ 192.168.56.200 (MetalLB)
┌─────────────────────────────────────────────────────────┐
│ VM: ops-demo (192.168.56.10) │
│ │
│ ┌──────────────────┐ ┌───────────────────────────┐ │
│ │ Ingress-Nginx │ │ ArgoCD │ │
│ │ (LB: .200) │ │ kijkt naar deze Git repo │ │
│ └──────┬───────────┘ └───────────┬───────────────┘ │
│ │ │ synct │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌───────────────────────────┐ │
│ │ podinfo │ │ MetalLB │ │
│ │ (Deployment) │ │ (geeft LAN IP's uit) │ │
│ └──────────────────┘ └───────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Tekton Pipeline │ │
│ │ clone → validate → bump tag → git push │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Laptop/browser
-> argocd.192.168.56.200.nip.io
-> podinfo.192.168.56.200.nip.io
-> grafana.192.168.56.200.nip.io
VirtualBox host-only netwerk
VM (k3s)
-> ingress-nginx + MetalLB
-> ArgoCD (app-of-apps)
-> Tekton (CI in-cluster)
-> podinfo (demo workload)
-> monitoring (bonus)
```
### De GitOps loop
### Componenten in 1 regel
1. Alles in de cluster staat als declaratie in deze Git repo
2. ArgoCD kijkt naar de repo en reconcilet de cluster naar die gewenste state
3. De Tekton pipeline wordt zelf ook door ArgoCD gedeployed, en pusht commits die ArgoCD daarna weer synct
4. De enige `kubectl apply` die je vandaag deed: bootstrap van ArgoCD + PipelineRun triggeren
| Component | Waarom die hier zit |
|-----------------------|----------------------------------------------|
| k3s | Lichtgewicht Kubernetes voor lokale labs |
| ArgoCD | GitOps controller |
| MetalLB | LoadBalancer IP op bare metal/VM |
| ingress-nginx | HTTP routing op hostnames |
| Tekton | Pipeline als Kubernetes resources |
| podinfo | Eenvoudige app om deploys zichtbaar te maken |
| kube-prometheus-stack | Metrics en dashboards |
### Stack recap
## 2. Waarom dit productie-relevant is
| Component | Rol |
|-----------------------|-----------------------------|
| k3s | Single-binary Kubernetes |
| ArgoCD | GitOps engine (App-of-Apps) |
| MetalLB | Bare-metal LoadBalancer |
| Ingress-Nginx | HTTP routing op hostname |
| Tekton | CI pipeline (in-cluster) |
| podinfo | Demo-applicatie |
| kube-prometheus-stack | Observability (bonus) |
### Zonder GitOps (klassieke drift)
---
## 2. Waarom GitOps in productie
### De oude manier: imperatieve deploys
> **VM**
> ```bash
> # Iemand draait dit op vrijdagmiddag
> kubectl set image deployment/api api=company/api:v2.3.1-hotfix
> # Geen review. Geen audit trail. Niemand weet wie dit om 16:47 deed.
> ```
### De GitOps manier
```
PR: "bump API naar v2.3.1-hotfix"
→ peer review
→ merge
→ ArgoCD synct
→ deploy gebeurt
→ Git commit IS de audit trail
```bash
kubectl set image deployment/api api=company/api:hotfix
```
### Belangrijkste voordelen
Dat werkt snel, maar je verliest context: geen review, lastig auditbaar, foutgevoelig.
**Audit trail**: Elke clusterwijziging heeft een Git commit: wie, wat, wanneer, waarom.
### Met GitOps
**Drift detection**: Als iemand direct `kubectl apply` doet, ziet ArgoCD drift en kan het automatisch terugdraaien. De cluster convergeert altijd terug naar wat in Git staat.
1. Wijziging gaat via commit/PR.
2. Review + merge.
3. ArgoCD sync.
4. Git geschiedenis is je audit trail en rollback-mechanisme.
**Disaster recovery**: Cluster weg? `vagrant up` + `./scripts/vm/bootstrap.sh` + `kubectl apply -f apps/root.yaml` en ArgoCD bouwt alles opnieuw op. Git is je backup.
Concreet voordeel:
**Samenwerking tussen teams**: Developers openen PR's voor deploys. Ops reviewt manifest-wijzigingen. Geen SSH-sleutels op productie nodig.
- Traceerbaarheid: wie veranderde wat en waarom.
- Driftcontrole: handmatige clusterwijzigingen vallen op.
- Herstelbaarheid: cluster kwijt -> opnieuw opbouwen vanuit Git.
- Samenwerking: app- en platformwijzigingen via hetzelfde proces.
**Rollback**: `git revert <commit>` + `git push`. Geen speciale tooling nodig.
## 3. App-of-Apps in het kort
### Het App-of-Apps pattern
`apps/root.yaml` verwijst naar onderliggende Argo Applications.
Eén root Application beheert alle andere Applications. Nieuwe service toevoegen = één YAML-file in `apps/` toevoegen. De root app pakt die automatisch op.
Dat betekent: nieuwe capability toevoegen = nieuwe app-definitie committen.
Geen losse handmatige installatiestappen op de cluster.
```
apps/root.yaml ──manages──► apps/argocd.yaml
apps/apps/podinfo.yaml
apps/networking/metallb.yaml
apps/networking/ingress-nginx.yaml
apps/ci/tekton.yaml
apps/ci/pipeline.yaml
apps/monitoring/prometheus-grafana.yaml
```
## 4. Grenzen van deze workshop-opzet
---
Dit is een leeromgeving. In productie zou je strakker willen op o.a.:
## 3. Wat is de volgende stap
- Secrets: geen PATs als plain K8s secrets in Git-workflow, maar Vault + ESO of vergelijkbaar.
- Security: PSA/namespace policies bewust hardenen i.p.v. versoepelen voor labs.
- Multi-cluster: ApplicationSets en promotieflow (dev -> staging -> prod).
- Delivery-strategie: canary/blue-green met meetbare rollback-criteria.
### Secrets management
## 5. Wat je mee moet nemen
Vandaag: plain Kubernetes Secrets met GitHub PATs.
In productie: **Vault + external-secrets-operator**
Als je 1 ding onthoudt:
```
Vault (secret store)
→ external-secrets-operator haalt secrets op
→ maakt Kubernetes Secrets aan
→ ArgoCD synct de rest
```
"Het cluster is een runtime-kopie van wat in Git staat."
### Multi-cluster met ApplicationSets
Niet andersom.
Vandaag: één cluster, één repo.
In productie: 10 clusters, één repo.
```yaml
# ArgoCD ApplicationSet: deploy podinfo naar elke cluster uit de lijst
generators:
- list:
elements:
- cluster: staging
- cluster: prod-eu
- cluster: prod-us
```
### Progressive delivery
Vandaag: rolling update (all-or-nothing).
In productie: **Argo Rollouts** met canary of blue/green.
```
Nieuwe versie → 5% van traffic
→ metrics goed → 20% → 50% → 100%
→ metrics slecht → auto-rollback
```
Dat principe maakt deployments voorspelbaar, bespreekbaar en herstelbaar.

View file

@ -0,0 +1,50 @@
---
marp: true
title: Intro workshop - GitOps in de praktijk
paginate: true
---
# GitOps in de praktijk
Korte intro (5 min)
---
## Doel van vandaag
- Een werkende GitOps-loop bouwen op lokale k3s
- Begrijpen waarom dit patroon productie-relevant is
- Eindigen met een reproduceerbare setup
---
## Agenda
1. VM + k3s klaarzetten
2. ArgoCD en app-of-apps
3. Ingress + MetalLB
4. Tekton pipeline
5. Bonus: monitoring
---
## Wat je leert
- Git als bron van waarheid
- Drift detectie en self-heal
- Samenhang tussen CI (Tekton) en CD (ArgoCD)
- Grenzen van een workshop-opzet
---
## Werkafspraak
- Kleine stappen
- Steeds verifiëren
- Problemen eerst observeren, dan repareren
---
# Klaar om te starten
Eerst baseline werkend, daarna optimaliseren.

View file

@ -0,0 +1,169 @@
%PDF-1.3
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/Contents 13 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 12 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
5 0 obj
<<
/Contents 14 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 12 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
6 0 obj
<<
/Contents 15 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 12 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
7 0 obj
<<
/Contents 16 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 12 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
8 0 obj
<<
/Contents 17 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 12 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
9 0 obj
<<
/Contents 18 0 R /MediaBox [ 0 0 841.8898 595.2756 ] /Parent 12 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
10 0 obj
<<
/PageMode /UseNone /Pages 12 0 R /Type /Catalog
>>
endobj
11 0 obj
<<
/Author (anonymous) /CreationDate (D:20260303233520+01'00') /Creator (anonymous) /Keywords () /ModDate (D:20260303233520+01'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (unspecified) /Title (untitled) /Trapped /False
>>
endobj
12 0 obj
<<
/Count 6 /Kids [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R ] /Type /Pages
>>
endobj
13 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 220
>>
stream
GarWs4U]+\&-h(+^Z$8<LY,8J9="ujT\u!<MeIgQoRiV4O(f.?/:f%YE6m>Po'e'Y>7^'?[Kck*\-GP4%<ohK,r(`_q3!9-VXt'"(2TfV*uVY1)]F(!a2VJ`-^k)1)Uj*$I+*6V>RS%:Y[LeIY`cp3CiWB.PD3Zo$ulm<dl@4c\:,JrV$6^-W3R-tm^l`qa''uq.g7@*)absX[,iA4aU=:U5m[~>endstream
endobj
14 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 345
>>
stream
GasJM4`A4\&;KrWMHB)k<XLQh6bGl_]2\(4fS.7FMtdA^PNM<M]2b%EOX^L(%c-a?%ZW(l5+h]^fGL]]3OjV8!7+dXo89YQb]s5W9mN_`=oJLO'N:hV;]nt<<i3_DpNKE)>(#%Qg6K)="3^f.nJ@TmlNo""])gG">:[[6j@V5Q<A?ku\^oD2Nt[5%qMOe%inH.>>OMg`r:-$.;UkQ_[Y.,1J$%=EWE:=%r(Q!E*Sb(j*7b>OTlL`tNPYK56h&WG*uup8[?MSfE;qDnJgH&^BYa;+X-96P#YK<6D_P&@fg$B'*et^+R_N8,TW;dl,u_@=&:u@5\XmAAV(NlmHiXTdIs:~>endstream
endobj
15 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 336
>>
stream
GasJMbA+pK&4Q?hM@8845pdXEQD3f15+n#(7/!KXN,(pA[_(eU=&DR3,[^b<\8[Ht1Q3k;:Aa>X=?A(*)(a_>?ptE?K-rTN\U_na\^\ACIg^9kg'ScP,#XhghuVG2X3ud4iWefkme0-b+'9RQK'@m0A@0jT'pLUe=Q`8pK\[DfW9&Q@.>n,RO/!6ce`R:=.@9k0)F7KuAc(s&+&I(8]\Uoo0haU5S>&=sLEsNcZM26JCYAQhBK#/_?5c7KUe&-B3+%_`5Z`*BWIgb:PosiG-TWWVg[HrQj3WNqD#5]H(RghjFI_;mCTSnbUkB;TNF?o)dmF(s@.jbWe9`n~>endstream
endobj
16 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 359
>>
stream
GasK8heU(_&-q]Ks,&Jr70eaqO!aR?dqoNe[_cAIP3H\]23g"fi*X7+)q1K'JKu5jkI<U6,Tbh"o.BHnA,O9]"nEtL@LDo]*qMZ>(Q_3)QhhQ\^Hefec9rF4,%`-(9\a*%o54Z]KUTu;&b7gMgHR<VR<4tWliLi52URsD-uG@13pjb8)h[<'^t()$I,j^-*VS(\P,cM$$KmT%/=!1q8i'g+!u;Sa*\%4OZrA^I9!\+I.nNm>jO&:[>B6Q_.tl6WNR[S(`A"2aBO!:Wm--&*mes/RcAL!a?Q-nnOlE0P:[UJ4%9%ZKNSh*SZb(!r#J)bIITP>PcUOC89IhP8"OkA0dhbkkI=bkr%K(g1cN~>endstream
endobj
17 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 289
>>
stream
GasK79hWAh&-h'>J&Me%<+MKOO4iYFkX?#6$XUJ^gBl@fC"S+<IQ*0%-%[ZVbJ<u`1P@5B.Ws>EpAsSM!bm;lA<fT.`^<jn^4rVa^>ZUq?[uY*[BB*kk>YIE@#O?O2bD'B%"4$'G_>L:E;RoA0q4$KV#C@BV)HP.@G*/,ljEM_hW*iGLJBO^Z1"OdbqA%2Pr$_2n^gWK5N!aMcq+!TW1;"U1BT;p]KJh:*CS=0ik-9W>pehHqq*&`+4F+?)j^Y%k?[FYf8?[bcs!^KjNBZpjrXk0T71Qg^]~>endstream
endobj
18 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 239
>>
stream
GarW36&G^u&4Q>bi\*fafThI3ZP@SWb?Q0b2:1%t,ouLOVLpi1,6^O+U#+fCRPIk:B`PR_X$)"jr"$js"+S87cYBW12H/K'Db;[uRM@pOb+[![j3$D4Y<sBu_JMORN&d[bE=RJL?bE($[[EeWe-E'le:sA"$sR;"f+ko]1hM,j;>MmP*g3Z=cV'dd/I("u\JmlmNKPQe&&R%0lM+0<S79sUcs!]^A?1_lr!.i,'+2uV3<~>endstream
endobj
xref
0 19
0000000000 65535 f
0000000061 00000 n
0000000102 00000 n
0000000209 00000 n
0000000321 00000 n
0000000526 00000 n
0000000731 00000 n
0000000936 00000 n
0000001141 00000 n
0000001346 00000 n
0000001551 00000 n
0000001621 00000 n
0000001883 00000 n
0000001973 00000 n
0000002284 00000 n
0000002720 00000 n
0000003147 00000 n
0000003597 00000 n
0000003977 00000 n
trailer
<<
/ID
[<ac7de3f3a6a4e42b2eb0900dbad51a23><ac7de3f3a6a4e42b2eb0900dbad51a23>]
% ReportLab generated PDF document -- digest (opensource)
/Info 11 0 R
/Root 10 0 R
/Size 19
>>
startxref
4307
%%EOF

View file

@ -0,0 +1,36 @@
# Intro talk (5 minuten)
## Opening
Welkom. In deze workshop bouwen we een kleine maar complete GitOps-keten op een lokale Kubernetes-VM.
Doel: niet alleen "iets werkend krijgen", maar snappen waarom dit patroon in echte omgevingen werkt.
## Wat we gaan doen
1. Een k3s-cluster opzetten in Vagrant.
2. ArgoCD installeren en een app-of-apps structuur gebruiken.
3. Networking toevoegen (Ingress + MetalLB) zodat apps bereikbaar zijn.
4. Een Tekton pipeline draaien die een wijziging naar Git terugschrijft.
5. (Bonus) Monitoring bekijken.
## Wat je onderweg leert
- Waarom "Git als bron van waarheid" nuttig is.
- Hoe ArgoCD drift detecteert en herstelt.
- Hoe CI (Tekton) en CD (ArgoCD) op elkaar aansluiten.
- Welke workshopkeuzes je in productie anders zou doen.
## Verwachting voor vandaag
Aan het eind heb je:
- Een reproduceerbaar lokaal platform-opzet.
- Begrip van de GitOps-loop van commit tot running workload.
- Een basis om dit patroon later uit te breiden naar meerdere clusters.
## Praktisch
- We werken met korte stappen en veel verificatie.
- Als iets niet meteen werkt: eerst status checken, dan pas fixen.
- Onthoud: fouten in deze workshop zijn juist nuttig, ze laten zien hoe het systeem reageert.