Voraussetzung: oc login
als cluster-admin für Schritt 2 (Operator-Installation), danach reicht
der Zugang zum Namespace library. Baut auf
operator-installieren-olm.html
auf – dort steht das allgemeine OLM-Verfahren.
1 Wer baut, verbraucht CPU
Baust du im Cluster, kostet jeder Build CPU und RAM, die den Diensten fehlen.
Baust du im Cluster, kostet jeder Build CPU und RAM, die deinen Diensten fehlen. Jenkins im Cluster (Master-Pod plus Agent-Pods je Build) ist der teure Weg. Der OpenShift-Weg: entweder Tekton (flüchtige Build-Pods, E2) oder CI außerhalb, die nur noch über ein ServiceAccount-Token deployt. Die Bibliothek baut außerhalb.
$JENKINS_HOME. Der OpenShift-Weg ist Tekton (flüchtige Build-Pods) oder CI außerhalb, die nur noch über ein ServiceAccount-Token in den Cluster deployt. Die Bibliothek baut außerhalb: Jenkins (lokales compose) pusht nach ghcr.io und ruft helm upgrade --install je Dienst als system:serviceaccount:library:pipeline – der Cluster sieht keine Build-Last.- Jenkins im Cluster: ein Master-Pod plus Agent-Pods je Build (Kubernetes-Plugin) – jeder Build kostet Cluster-CPU, konkurriert mit den Diensten, braucht ein PVC für
$JENKINS_HOME - die alte OpenShift-Jenkins-Vorlage (Templates, OAuth-Login, S2I-Jenkinsfile) wird nicht mehr gepflegt – keine Neuanlage
- der OpenShift-Weg, Variante Tekton (E2): Build-Pods, aber zweckgebaut und flüchtig – kein Master, kein PVC, ein
PipelineRunje Lauf - der OpenShift-Weg, Variante CI außerhalb: GitHub Actions / GitLab CI / externer Jenkins baut außerhalb und deployt nur über ein SA-Token in den Cluster
- Faustregel: baue dort, wo CPU billig ist – deploye dort, wo die App läuft
- Bibliothek: Jenkins läuft außerhalb in einem lokalen docker-compose, baut je Dienst ein Image und pusht nach
ghcr.io - dann ruft Jenkins je Dienst
helm upgrade --install catalog ./chart -n library --atomic - authentifiziert als
system:serviceaccount:library:pipeline, gebunden anadmin,system:image-builderundregistry-editorinlibrary(A5) - der Cluster sieht nur
helm upgrade-Aufrufe – keine Build-Pods, kein Jenkins-Pod, kein PVC - Abwägung Control Plane: Jenkins-im-Cluster belastet sie stark, extern-bauen kaum
- Abwägung Secrets: intern hat Jenkins alles, extern muss man ein Deploy-Token und Registry-Zugang nach außen geben
- Abwägung Portabilität: externe CI läuft gegen jeden Cluster gleich, Jenkins-im-Cluster ist an diesen einen gebunden
- ein Deploy von außen braucht genau ein Token mit gerade den nötigen Rollen – nicht
cluster-admin - OCP-Unterschied: die Jenkins-Vorlage ist OpenShift-eigen – Tekton kommt als OpenShift-Pipelines-Operator, ist aber Standard-Kubernetes-Tekton
| Modell | was läuft | Last auf der Control Plane |
|---|---|---|
| Jenkins im Cluster | ein Master-Pod (dauerhaft) + Agent-Pods je Build, PVC für $JENKINS_HOME | hoch, konkurriert mit den Diensten |
| Tekton (dieser Guide) | ein Pod je TaskRun, danach weg – kein Master, kein PVC für einen Server | nur während des Laufs |
| CI außerhalb (die Bibliothek) | baut komplett extern, deployt nur über ein SA-Token | praktisch keine |
Faustregel aus dem Atlas: baue dort, wo CPU billig ist, deploye dort, wo die App läuft. Tekton ist der Mittelweg – Build-Last im Cluster, aber flüchtig statt dauerhaft. Die alte OpenShift-Jenkins-Vorlage (Templates, OAuth-Login, S2I-Jenkinsfile) wird nicht mehr gepflegt, keine Neuanlage.
2 Den Pipelines-Operator installieren
Tekton kommt als OpenShift-Pipelines-Operator – Standard-Tekton darunter, plus Konsolen-Integration.
oc get csv -A | grep -i pipelines # schon installiert? cat <<'EOF' | oc apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: openshift-pipelines-operator namespace: openshift-operators spec: channel: latest name: openshift-pipelines-operator-rh source: redhat-operators sourceNamespace: openshift-marketplace EOF oc get csv -n openshift-operators -w # bis Phase Succeeded
Der Operator bringt die CRDs Task, Pipeline,
TaskRun, PipelineRun mit, und den
pipeline-ServiceAccount, der in jedem Namespace automatisch entsteht,
sobald der erste Tekton-Lauf dort startet.
3 Einen Task schreiben und laufen lassen
Ein Task ist eine geordnete Liste von steps –
jeder Step ein Container.
Tekton ist CI als Kubernetes-Objekte. Ein Task ist eine Reihe von steps, jeder Step ein Container. Eine Pipeline reiht Tasks. Ein PipelineRun ist ein Lauf und erzeugt Pods. Daten zwischen Tasks fließen über Workspaces. Alles flüchtig – kein Master, kein PVC für einen Server.
Task ist eine Reihe von steps, jeder ein Container. Eine Pipeline ordnet Tasks (Reihenfolge oder DAG). Ein PipelineRun ist ein Lauf und erzeugt je Task einen Pod – diese laufbezogenen Pods und Objekte werden nach dem Lauf durch konfigurierte Cleanup-/Retention-Regeln bereinigt; kein Master, kein PVC für einen Server. Daten zwischen Tasks fließen über Workspaces (ein PVC, emptyDir, ein Secret). Ein EventListener mit TriggerBinding und TriggerTemplate macht aus einem Git-Webhook einen PipelineRun.- ein
Taskist eine geordnete Liste vonsteps– jeder Step ist ein Container (Image + Kommando), die Steps teilen sich einen Pod - eine
Pipelineist eine geordnete oder DAG-Anordnung von Tasks –runAfterordnet, sonst laufen sie parallel,finally-Tasks laufen immer paramsgehen rein,resultskommen raus – so gibt ein Task den Image-Digest an den nächsten weiter- ein
PipelineRunist eine Ausführung – er erzeugt je Task einenTaskRunund je TaskRun einen Pod - der PipelineRun läuft als der
pipeline-SA (A6) – dessen RBAC begrenzt, was die Pipeline anfassen darf - Cleanup/Retention bereinigt die laufbezogenen Pods und TaskRuns nach dem Lauf – kein dauerhafter Server-Prozess wie bei Jenkins (E1), Cluster-CPU fällt nach dem Lauf wieder ab
- ein
Workspaceist geteilter Speicher zwischen Tasks: ein PVC (bleibt),emptyDir(nur der Run), oder eine ConfigMap / ein Secret - so kommt der geklonte Code von
clonezubuild, und der Maven-Cache als PVC-Workspace macht Builds schneller - Triggers: ein
EventListener(Pod + Route) nimmt den Webhook an,TriggerBindingzieht Werte aus dem Payload,TriggerTemplateist die PipelineRun-Vorlage - Interceptors prüfen die Webhook-Signatur und filtern (nur
main) – Alternative:tkn pipeline startoder ein Cron-PipelineRun - wiederverwendbare Tasks aus dem Tekton Hub oder als
ClusterTask:git-clone,buildah,s2i - Werkzeuge: die
tkn-CLI (tkn pr logs -f), der OpenShift-Pipelines-Operator mit Konsolen-Ansicht (DAG live, grün/rot je Task) - Bibliothek:
git-clone → mvn test → buildah → helm upgradeje Dienst wäre der Weg weg von Jenkins (E1) und rein in den Cluster - OCP-Unterschied: der Operator heißt OpenShift Pipelines und bringt Konsolen-Integration und Extra-ClusterTasks – darunter ist Standard-Tekton
cat <<'EOF' | oc apply -f -
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: demo-check
namespace: library
spec:
params:
- name: nachricht
type: string
default: "Tekton laeuft"
steps:
- name: begruessen
image: registry.access.redhat.com/ubi9/ubi-minimal:latest
script: |
#!/bin/sh
echo "$(params.nachricht)"
- name: umgebung-zeigen
image: registry.access.redhat.com/ubi9/ubi-minimal:latest
script: |
#!/bin/sh
echo "laeuft als: $(whoami 2>/dev/null || id -u)"
cat /etc/os-release | head -3
EOF
cat <<'EOF' | oc apply -f -
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
name: demo-check-run-1
namespace: library
spec:
taskRef:
name: demo-check
params:
- name: nachricht
value: "Hallo aus dem ersten TaskRun"
EOF
tkn taskrun logs demo-check-run-1 -n library -f
# ohne tkn-CLI: oc logs -f -l tekton.dev/taskRun=demo-check-run-1 -n library --all-containers
Die zwei Steps teilen sich einen Pod, laufen aber nacheinander –
im Pod stehen sie als step-begruessen und step-umgebung-zeigen.
Nach dem Lauf bleibt der TaskRun als Objekt für die Historie, der Pod
selbst verschwindet nach kurzer Zeit (Completion-TTL).
4 Zwei Tasks zu einer Pipeline verketten
Eine Pipeline ordnet Tasks, ein Workspace gibt
ihnen geteilten Speicher – genau das Muster, das git-clone → build
in der echten Build-Kette nutzt.
cat <<'EOF' | oc apply -f -
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: demo-schreiben
namespace: library
spec:
workspaces:
- name: teilen
steps:
- name: datei-schreiben
image: registry.access.redhat.com/ubi9/ubi-minimal:latest
script: |
#!/bin/sh
echo "erzeugt um $(date -Iseconds)" > $(workspaces.teilen.path)/marker.txt
---
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: demo-lesen
namespace: library
spec:
workspaces:
- name: teilen
steps:
- name: datei-lesen
image: registry.access.redhat.com/ubi9/ubi-minimal:latest
script: |
#!/bin/sh
echo "gefunden:"
cat $(workspaces.teilen.path)/marker.txt
EOF
cat <<'EOF' | oc apply -f -
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: demo-pipeline
namespace: library
spec:
workspaces:
- name: geteilt
tasks:
- name: schreiben
taskRef: { name: demo-schreiben }
workspaces:
- { name: teilen, workspace: geteilt }
- name: lesen
taskRef: { name: demo-lesen }
runAfter: ["schreiben"]
workspaces:
- { name: teilen, workspace: geteilt }
EOF
runAfter erzwingt die Reihenfolge – ohne die Zeile würden
schreiben und lesen parallel starten, und lesen
fände die Datei noch nicht.
5 Den PipelineRun live beobachten
Ein PipelineRun ist ein Lauf – er erzeugt je Task einen
TaskRun, je TaskRun einen Pod.
cat <<'EOF' | oc apply -f -
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: demo-pipeline-run-1
namespace: library
spec:
pipelineRef:
name: demo-pipeline
workspaces:
- name: geteilt
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources: { requests: { storage: 1Gi } }
EOF
tkn pipelinerun logs demo-pipeline-run-1 -n library -f
oc get taskrun -n library -l tekton.dev/pipelineRun=demo-pipeline-run-1
oc get pipelinerun demo-pipeline-run-1 -n library -o jsonpath='{.status.conditions[0].status} {.status.conditions[0].reason}{"\n"}'
Das volumeClaimTemplate im Workspace erzeugt ein frisches PVC nur für
diesen Lauf – nach dem Löschen des PipelineRuns bleibt es stehen (Aufräumen
unten). In der Konsole zeigt der Pipelines-Tab den DAG live, grün
sobald ein Task fertig ist.
MerkeNach dem Lauf sind die Pods weg
– kein Server-Prozess wie bei Jenkins. Die Objekte TaskRun und
PipelineRun bleiben für die Historie, bis sie aufgeräumt werden.
6 Typische Fallen
| Symptom | meist |
|---|---|
PipelineRun hängt in PipelinePending | der pipeline-ServiceAccount fehlt oder das PVC im Workspace kann nicht gebunden werden |
lesen-Task findet die Datei nicht | runAfter fehlt – Tasks liefen parallel, nicht nacheinander |
Step schlägt mit permission denied fehl | SCC-Restriktion (A7) – das Skript versucht etwas, das der Pod-Security-Kontext nicht erlaubt |
TaskRun bleibt ewig Pending | ResourceQuota im Namespace ist voll (B7) – kein Platz für einen weiteren Pod |
| Operator-Installation hängt | CSV in openshift-operators prüfen, oft ein fehlender Katalog-Sync |
7 Wie das Projekt es macht
Die Bibliothek baut nicht mit Tekton – Jenkins läuft
außerhalb in einem lokalen docker-compose, pusht Images nach ghcr.io
und ruft helm upgrade --install catalog ./chart -n library --atomic
als system:serviceaccount:library:pipeline
(build-kette-openshift.html).
Der Cluster sieht dabei keine Build-Pods. Diese Anleitung zeigt das
Alternativmuster, das der Atlas als nächsten Schritt nennt: dieselben
Stufen git-clone → mvn test → buildah → helm upgrade als
Tekton-Pipeline statt als Jenkinsfile – mit git-clone als
wiederverwendbarem ClusterTask aus dem Tekton Hub anstelle von
demo-schreiben.
+ Die Kurzfassung
runAfter, sonst laufen sie parallelemptyDir oder ein Secret