Eine vollständige Kubernetes Pipeline für eine Spring Boot App in einem Container. Spring Boot Helloworld App → Tekton baut das Image → lokale k3s-Registry → ArgoCD deployt per Helm.
Verwendet ConfigMap, Secrets, SSL Certificate, Istio Gateway, VirtualService, HealthChecks, Readness Checks. ServiceEntry und DestinationRule für eine externe Datenbankabhängigkeit. Hat ein Feature Flag für den Wechsel von h2 auf MySQL.
Alle notwendigen Dateien, Zugangsdaten und Installationsanleitungen sind über die Workshop-Homepage abrufbar:
Die Seite ist in folgende Tabs gegliedert:
| Tab | Inhalt |
|---|---|
| Cluster | Cluster-IP-Adressen, ArgoCD-URL mit Zugangsdaten, ArgoCD-CLI-Login |
| kubectl | kubeconfig.yaml herunterladen und einrichten (Linux / macOS / Windows) |
| Apps | Direkte Links zur helloworld- und demo-App |
| Registry | Registry-URL (registry.big.lan), Image bauen und pushen, Insecure-Registry-Konfiguration |
| CA-Zertifikat | Workshop-CA-Zertifikat (ca.pem) herunterladen und im System sowie in Docker hinterlegen |
| Maven | Nexus-Cache (maven.big.lan:8081), settings.xml herunterladen und einrichten |
| Tools | Download-Anleitungen für kubectl, argocd, helm und tkn (Tekton CLI) |
| Spring MCP | Spring Boot MCP-Server aufbauen (Spring AI, @Tool-Annotation, SSE-Transport) |
- kubeconfig herunterladen (Tab kubectl) und
KUBECONFIGsetzen - CA-Zertifikat installieren (Tab CA-Zertifikat) — für Browser, kubectl und Docker
- Maven settings.xml nach
~/.m2/kopieren (Tab Maven) — nutzt den lokalen Nexus-Cache - Tools installieren:
kubectl,argocd,helm,tkn(Tab Tools) - Verbindung testen:
kubectl get nodes
kubectl apply -f tekton/git-clone.yamlkubectl apply -f tekton/serviceaccount.yaml
kubectl apply -f tekton/task-maven-build.yml
kubectl apply -f tekton/task-kaniko.yml
kubectl apply -f tekton/pipeline.ymlkubectl create -f tekton/pipeline-run.yml
kubectl createstattapply, damitgenerateNameeine eindeutige Run-ID vergibt.
Logs verfolgen (Name des Runs ermitteln und dann):
kubectl get pipelinerun
kubectl logs -l tekton.dev/pipeline=helloworld-pipeline --all-containers -fOder mit der Tekton CLI:
tkn pipelinerun logs --last -fDer Run durchläuft drei Schritte:
- clone — Repository auschecken
- build-jar — Maven-Build mit Spring Boot AOT (
compile → process-aot → package) - docker-push — Kaniko baut das Docker-Image und pusht nach
registry.registry.svc.cluster.local:5000/helloworld:latest
kubectl run registry-check --image=curlimages/curl --restart=Never --rm -it -- \
curl http://registry.registry.svc.cluster.local:5000/v2/helloworld/tags/listErwartet: {"name":"helloworld","tags":["latest"]}
# ArgoCD-Projekt anlegen (muss vor der Application existieren)
kubectl apply -f argocd/helloteam-project.yaml
# ArgoCD-Application anlegen
kubectl apply -f argocd/hello-namespace.yml
kubectl apply -f argocd/app-helloworld.ymlArgoCD erkennt Änderungen im Git-Repository automatisch (auto-sync ist aktiv).
Für einen manuellen Sync zuerst einloggen:
# Admin-Passwort auslesen
kubectl get secret argocd-initial-admin-secret -n argocd \
-o jsonpath='{.data.password}' | base64 -d
# Einloggen
argocd login argocd.tp.lan --username admin
# Sync auslösen
argocd app sync helloworldAlternativ direkt im ArgoCD-UI: https://argocd.tp.lan → Projekt helloteam → Application helloworld.
kubectl get pods -n helloworld
kubectl get certificate -n helloworld
kubectl get gateway -n helloworldApp über den Istio-Ingress erreichbar unter https://helloworld.tp.lan.
Health-Endpoint prüfen:
curl https://helloworld.tp.lan/actuator/healthLiveness- und Readiness-Status einzeln abrufen:
curl https://helloworld.tp.lan/actuator/health/readinessDer ProbeController erlaubt es, den Liveness- und Readiness-Zustand per GET-Request zu setzen — nützlich zum Testen der Kubernetes-Probes ohne Neustart:
| Endpunkt | Effekt | Actuator-Status |
|---|---|---|
GET /control/health/ok |
Liveness → CORRECT | /actuator/health/liveness → UP |
GET /control/health/notok |
Liveness → BROKEN | /actuator/health/liveness → DOWN |
GET /control/ready/ok |
Readiness → ACCEPTING_TRAFFIC | /actuator/health/readiness → UP |
GET /control/ready/notok |
Readiness → REFUSING_TRAFFIC | /actuator/health/readiness → DOWN |
# Liveness auf "not ok" setzen → Kubernetes startet den Pod neu
curl https://helloworld.tp.lan/control/health/notok
# Readiness auf "not ok" setzen → Kubernetes nimmt den Pod aus dem Load Balancer
curl https://helloworld.tp.lan/control/ready/notok
# Wieder auf ok setzen
curl https://helloworld.tp.lan/control/health/ok
curl https://helloworld.tp.lan/control/ready/ok| Endpunkt | Inhalt |
|---|---|
/ |
Startseite mit Links zu allen Endpunkten, App-Version und Pod-Name |
/application |
Alle aktiven application.properties-Werte als JSON |
/db |
Datenbankverbindung: Typ, Version, JDBC-URL |
curl https://helloworld.tp.lan/application
curl https://helloworld.tp.lan/dbIm h2-Modus (Standard) liefert /db:
{"connected":true,"type":"H2","version":"2.x.x","url":"jdbc:h2:mem:..."}Der Chart deployt zwei Versionen derselben App parallel und routet Traffic anhand des Aufrufer-Namespace per Istio. Beschreibung, Testclient-Setup und busybox-Testbefehle: kunden-traffic.md
# Chart auf Syntaxfehler prüfen
helm lint helmchart/
# Templates rendern und ausgeben (kein Cluster nötig)
helm template helloworld helmchart/ --namespace helloworld
# Dry-run gegen den Cluster (validiert auch gegen die Kubernetes API)
helm install helloworld helmchart/ --namespace helloworld --create-namespace --dry-run# Erstinstallation
helm install helloworld helmchart/ --namespace helloworld --create-namespace
# Update (auch für Erstinstallation verwendbar)
helm upgrade --install helloworld helmchart/ --namespace helloworldhelm status helloworld --namespace helloworld
helm list --namespace helloworld# Release entfernen (Namespace bleibt erhalten)
helm uninstall helloworld --namespace helloworld
# Namespace ebenfalls löschen
kubectl delete namespace helloworldWechsel von der In-Memory-H2-Datenbank auf eine externe MySQL-Instanz über das Feature Flag
mysql.external.enabled. Schritt-für-Schritt-Anleitung inkl. DNS-Check und Verifikation:
db-schwenk.md
JSON-Logging für Log-Aggregation (Loki, Elasticsearch) aktivieren — in values.yaml:
logging:
structured:
enabled: true
format: ecs # Elastic Common Schema — kompatibel mit Loki, ELK, KibanaIm Standard (enabled: false) loggt die App im Text-Format, das für lokale Entwicklung lesbar ist.