14 KiB
Oefening 04 — Tekton Pipeline
Tijd: ~45 minuten Doel: Een pipeline bouwen die automatisch de image-tag in Git aanpast en ArgoCD de update laat uitrollen — de volledige GitOps CI/CD-loop.
Wat je leert
- Tekton-concepten: Task, Pipeline, PipelineRun, Workspace
- Hoe een pipeline via een Git-commit een GitOps-deployment triggert (geen container registry nodig)
- De volledige loop: pipeline push → ArgoCD detecteert → rolling update → nieuwe versie in browser
Leeswijzer
Voor beginners (optioneel): Oefening 04 heeft de meeste moving parts. 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
Jij triggert een PipelineRun
│
▼
Task 1: clone repo
Task 2: valideer manifests (kubectl dry-run)
Task 3: pas image-tag aan → deployment.yaml: 6.6.2 → 6.7.0
Task 4: git commit + push
│
▼
ArgoCD detecteert de commit
│
▼
ArgoCD synchroniseert de podinfo Deployment
│
▼
Rolling update → podinfo v6.7.0 in je browser
Vereisten
Oefeningen 01–03 afgerond. podinfo is bereikbaar via http://podinfo.192.168.56.200.nip.io en toont versie 6.6.2.
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
Stappen
1. Tekton installeren via ArgoCD
manifests/ci/tekton/kustomization.yaml
resources:
- https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.65.1/release.yaml
patches:
- path: namespace-podsecurity-patch.yaml
target:
kind: Namespace
name: tekton-pipelines
Waarom dit:
release.yamlinstalleert Tekton Pipelines (controller, webhook, CRDs).- De
patchesregel past de namespace aan die al in de upstream release zit. - 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,seccompProfileenallowPrivilegeEscalation=false. - Tekton runtime-pods (zoals
prepareenstep-*) voldoen in deze setup niet altijd aan die eisen, waardoor je directPodAdmissionFailedkrijgt voordat je pipeline-logica start.
manifests/ci/tekton/namespace-podsecurity-patch.yaml
apiVersion: v1
kind: Namespace
metadata:
name: tekton-pipelines
labels:
pod-security.kubernetes.io/enforce: privileged
Waarom dit:
- Tekton maakt zelf tijdelijke pods aan per TaskRun (
prepare,step-*). - Met
enforce=restrictedworden die pods in deze workshop-setup afgewezen. - Deze patch maakt de oefening reproduceerbaar op de single-node VM.
enforce=privilegedbetekent hier niet "alles in je cluster is onveilig", maar alleen dat deze ene namespace niet door PSA wordt geblokkeerd.- We kiezen dit bewust als workshop trade-off: focus op GitOps/Tekton-flow, niet op PSA-hardening.
- In productie kies je meestal niet
privileged, maar harden je de Tekton setup zodat hij onderbaseline/restricteddraait.
apps/ci/tekton.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: tekton
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "5"
spec:
project: workshop
source:
repoURL: JOUW_FORK_URL
targetRevision: HEAD
path: manifests/ci/tekton
destination:
server: https://kubernetes.default.svc
namespace: tekton-pipelines
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
HOST
git add apps/ci/tekton.yaml manifests/ci/tekton/ git commit -m "feat: installeer Tekton via ArgoCD" git push
Wacht tot Tekton draait (~3–5 minuten):
VM
kubectl get pods -n tekton-pipelines # tekton-pipelines-controller-xxx 1/1 Running # tekton-pipelines-webhook-xxx 1/1 Running
Wat je hier valideert:
- De Tekton controller verwerkt Pipeline/Task resources.
- De Tekton webhook default/valideert objecten bij
kubectl apply. - Als deze pods niet
Runningzijn, heeft het geen zin om door te gaan.
2. Pipeline-resources aanmaken
manifests/ci/pipeline/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: pipeline-runner
namespace: tekton-pipelines
Waarom dit:
- Deze serviceaccount draait de pipeline pods.
- Alle permissies voor
validateen 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:
HOST
git show origin/solution/04-tekton-pipeline:manifests/ci/pipeline/pipeline.yaml
Wat er in die pipeline zit:
clone: clonet jouw repo met credentials uitgit-credentials.validate: doet client-side manifestvalidatie op de podinfo manifests.bump-image-tag: wijzigt de image tag indeployment.yaml.git-commit-push: commit + push naarmain, waarna ArgoCD de wijziging oppakt.
manifests/ci/pipeline/pipelinerun.yaml
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: bump-podinfo-to-670
namespace: tekton-pipelines
spec:
pipelineRef:
name: gitops-image-bump
taskRunTemplate:
serviceAccountName: pipeline-runner
params:
- name: repo-url
value: JOUW_FORK_URL
- name: new-tag
value: "6.7.0"
workspaces:
- name: source
volumeClaimTemplate:
spec:
accessModes: [ ReadWriteOnce ]
resources:
requests:
storage: 1Gi
- name: git-credentials
secret:
secretName: git-credentials
Waarom deze velden belangrijk zijn:
pipelineRef: kiest welke pipeline je start.params: bepaalt repo en doelversie zonder de pipeline-definitie te wijzigen.workspaces.source: tijdelijk werkvolume voor clone/edit/commit.workspaces.git-credentials: secret mount voor Git auth.
apps/ci/pipeline.yaml
Belangrijk:
- Dit bestand is alleen de ArgoCD
Applicationwrapper. - Daarom is het klein en zie je hier geen Tekton-steps.
- De echte pipeline-steps staan in
manifests/ci/pipeline/pipeline.yaml(clone, validate, bump-image-tag, git-commit-push). - ArgoCD beheert dus alleen Tekton resources; de pipeline runtime gebeurt in Tekton zelf.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: workshop-pipeline
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "7"
spec:
project: workshop
source:
repoURL: JOUW_FORK_URL
targetRevision: HEAD
path: manifests/ci/pipeline
destination:
server: https://kubernetes.default.svc
namespace: tekton-pipelines
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
HOST
git add apps/ci/pipeline.yaml manifests/ci/pipeline/ git commit -m "feat: voeg pipeline-resources toe" git push
3. Tekton Dashboard zichtbaar maken (UI)
Maak een aparte Tekton Dashboard app, met Ingress zodat je PipelineRuns in de browser ziet.
manifests/ci/dashboard/kustomization.yaml
resources:
- https://storage.googleapis.com/tekton-releases/dashboard/latest/release-full.yaml
- ingress.yaml
Waarom dit:
release-full.yamlinstalleert de dashboard backend + service.ingress.yamlmaakt de UI bereikbaar via dezelfde ingress-nginx die je in oefening 03 bouwde.- Een losse
ingress.yamlzou ArgoCD ook zonder Kustomize kunnen toepassen. - We gebruiken Kustomize hier omdat je in een
resources:lijst zowel een remote upstream manifest als lokale manifests in een app kunt combineren. - Daardoor hoef je de upstream Tekton Dashboard YAML niet in je eigen repo te kopieeren, maar kun je wel lokaal je eigen Ingress toevoegen.
manifests/ci/dashboard/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-dashboard
namespace: tekton-pipelines
spec:
ingressClassName: nginx
rules:
- host: tekton.192.168.56.200.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tekton-dashboard
port:
number: 9097
apps/ci/tekton-dashboard.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: tekton-dashboard
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "6"
spec:
project: workshop
source:
repoURL: JOUW_FORK_URL
targetRevision: HEAD
path: manifests/ci/dashboard
destination:
server: https://kubernetes.default.svc
namespace: tekton-pipelines
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
HOST
git add apps/ci/tekton-dashboard.yaml manifests/ci/dashboard/ git commit -m "feat: voeg Tekton Dashboard met ingress toe" git push
Open daarna: http://tekton.192.168.56.200.nip.io
4. Git-credentials instellen
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.
Direct links:
- Fine-grained token: https://github.com/settings/personal-access-tokens/new
- Classic token: https://github.com/settings/tokens/new
VM
/vagrant/scripts/vm/set-git-credentials.sh <jouw-github-gebruikersnaam> <jouw-pat>
Dit maakt een Kubernetes Secret aan in het cluster — het PAT komt niet in Git.
Tip:
- Bij GitHub PAT over HTTPS kun je als username je GitHub username gebruiken.
x-access-tokenals username werkt vaak ook, zolang password de PAT is.
5. Pipeline triggeren
Controleer eerst dat stap 3 gelukt is. Pas daarna de PipelineRun starten:
VM
kubectl apply -f manifests/ci/pipeline/pipelinerun.yaml
Volg de voortgang:
VM
kubectl get pipelinerun -n tekton-pipelines -w
Of per pod:
VM
kubectl get pods -n tekton-pipelines -w
De PipelineRun duurt ~2–3 minuten.
Wat je zou moeten zien:
- eerst
clone, - daarna
validate, - dan
bump-image-tag, - en als laatste
git-commit-push.
6. Controleer de commit
HOST
git fetch origin git log origin/main --oneline -3 # Je ziet: chore(pipeline): bump podinfo to 6.7.0
7. ArgoCD laten synchroniseren
Klik Refresh op de podinfo application in ArgoCD, of wacht op het automatische poll-interval.
VM
kubectl rollout status deployment/podinfo -n podinfo
Waarom dit nodig is:
- De pipeline praat niet direct met de podinfo Deployment.
- De pipeline pusht alleen Git; ArgoCD voert de daadwerkelijke rollout uit.
8. Controleer in de browser
Open http://podinfo.192.168.56.200.nip.io — je ziet nu versie 6.7.0.
HOST
curl http://podinfo.192.168.56.200.nip.io | jq .version # "6.7.0"
Pipeline opnieuw uitvoeren
De naam van een PipelineRun moet uniek zijn:
VM
kubectl delete pipelinerun bump-podinfo-to-670 -n tekton-pipelines kubectl apply -f manifests/ci/pipeline/pipelinerun.yaml
Probleemoplossing
| Symptoom | Oplossing |
|---|---|
| PipelineRun blijft "Running" | kubectl describe pipelinerun -n tekton-pipelines bump-podinfo-to-670 |
Secret git-credentials niet gevonden |
Run in VM: ./scripts/vm/set-git-credentials.sh ... (na vagrant ssh + cd /vagrant) of vanaf host: vagrant ssh -c \"/vagrant/scripts/vm/set-git-credentials.sh ...\" |
| Push mislukt: 403 Forbidden | PAT heeft onvoldoende rechten — repo-scope vereist |
| ArgoCD synchroniseert niet | Klik Refresh in de UI |
root blijft OutOfSync op app tekton |
Verwijder de lege kustomize: {} uit apps/ci/tekton.yaml (Argo normaliseert deze weg in live state) |
PipelineRun faalt met PodAdmissionFailed |
Controleer dat tekton-pipelines label pod-security.kubernetes.io/enforce=privileged heeft (via manifests/ci/tekton/namespace-podsecurity-patch.yaml) |
| Tekton Dashboard toont standaard Nginx/404 | Controleer apps/ci/tekton-dashboard.yaml en manifests/ci/dashboard/ingress.yaml host/service/poort |
Volgende stap
In Oefening 05 kijk je terug op wat je gebouwd hebt en experimenteer je met drift detection.