Basierend auf dem vorherigen Tutorial über das Betreiben von Jenkins in einem Kubernetes-Cluster ist es jetzt an der Zeit, die Kubernetes-Infrastruktur zu nutzen, um Build-Jobs über den Cluster zu skalieren.
Beispiel-Build-Jobs
Erstelle zuerst zwei Projekte, um das Setup zu testen. Die Jobs werden nichts Nützliches tun - sie werden nur 10 Sekunden warten und dann beenden.
Erstelle die Jobs, indem du im Dashboard auf “New Item” klickst und “Freestyle Project” auswählst.

Im Abschnitt “Build” füge einen “Execute shell”-Build-Schritt hinzu.

Der Befehl, den der Build-Job ausführen soll, ist:
sleep 10

Nach dem Speichern erscheint der neue Job im Dashboard. Erstelle einen weiteren Job, sodass es insgesamt zwei gibt.
Wenn beide Jobs gleichzeitig ausgelöst werden, erscheinen sie unter “Build Executor Status”.

Vorerst werden beide Jobs innerhalb des Jenkins-Pods ausgeführt. Das wird langfristig nicht skalieren.
Das Ziel ist, jede Build-Job-Instanz in einem neu erstellten Pod auszuführen, dessen Lebenszyklus an den Build-Job gebunden ist:
- Wenn ein Job ausgelöst wird, wird ein neuer Pod erstellt.
- Der Job läuft innerhalb dieses Pods.
- Wenn der Job beendet ist, wird der Pod gelöscht.
Um dies zu erreichen, ist zusätzliche Konfiguration erforderlich.
Kubernetes-Plugin installieren
Installiere das Kubernetes-Plugin über:
- Manage Jenkins
- Manage Plugins

Dann:
- Available
- wähle “Kubernetes”
- klicke “Install without restart”

Das Plugin wird installiert:

Kubernetes-Secrets hinzufügen
Zwei Kubernetes-Secrets (Service-Accounts + RBAC) werden benötigt.
Das erste ist jenkins-robot.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-robot
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-robot
namespace: jenkins
labels:
"app.kubernetes.io/name": 'jenkins'
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods", "pods/exec", "persistentvolumeclaims", "events"]
verbs: ["create", "apply", "delete", "deletecollection", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins-robot-binding
namespace: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins-robot
subjects:
- kind: ServiceAccount
name: jenkins-robot
namespace: jenkins
Das zweite ist jenkins-robot-global.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-robot-global
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jenkins-robot-global
namespace: jenkins
labels:
"app.kubernetes.io/name": 'jenkins'
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods", "pods/exec", "persistentvolumeclaims"]
verbs: ["create", "apply", "delete", "deletecollection", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-robot-global-binding
namespace: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins-robot-global
subjects:
- kind: ServiceAccount
name: jenkins-robot-global
namespace: jenkins
Wende beide Manifeste an:
kubectl apply -n jenkins -f jenkins-robot.yaml
kubectl apply -n jenkins -f jenkins-robot-global.yaml
Diese Secrets müssen zu Jenkins hinzugefügt werden.
Rufe das erste Secret ab mit:
kubectl -n jenkins get serviceaccount jenkins-robot --template='{{range.secrets}}{{.name}}{{"\n"}}{{end}}' | xargs -n 1 kubectl -n jenkins get secret --template='{{ if.data.token }}{{.data.token }}{{end}}' | head -n 1 | base64 -d -
Kopiere das resultierende Token in die Zwischenablage, um es im nächsten Schritt einzufügen.
Erstelle in Jenkins die Credential über:
- Manage Jenkins
- Manage Credentials

Dann klicke:
- New Item

Navigiere zu:
- Global credentials (unrestricted)

Dann:
- Add credentials

Gib diese Werte ein:
- Kind: Secret text
- Scope: Global
- Secret:
<the secret from the clipboard> - ID: Jenkins-Robot

Wiederhole für das jenkins-robot-global-Secret, das abgerufen werden kann mit:
kubectl -n jenkins get serviceaccount jenkins-robot-global --template='{{range.secrets}}{{.name}}{{"\n"}}{{end}}' | xargs -n 1 kubectl -n jenkins get secret --template='{{ if.data.token }}{{.data.token }}{{end}}' | head -n 1 | base64 -d -

Beide Credentials sollten jetzt in Jenkins erscheinen:

Die Kubernetes-Cloud zu Jenkins hinzufügen
Jenkins muss mit dem Kubernetes-Cluster konfiguriert werden, den es verwenden wird. Füge die Kubernetes-Cloud hinzu über:
- Manage Jenkins
- Manage Nodes and Clouds
- Configure Clouds
- Add a new cloud: Kubernetes

Unter “Kubernetes Cloud Details” gib an:
- Name: Kubernetes
- Kubernetes URL:
https://<k8s-master-ip>:6443 - Kubernetes Namespace: jenkins
- Credentials: Jenkins-Robot
- Jenkins Tunnel:
<ip>:50000
Die IP des Cluster-Master-Nodes kann gefunden werden mit:
kubectl get nodes -o wide | grep master
Die IP für den Jenkins-Tunnel ist die IP des jenkins-jnlp-Service:
kubectl get service jenkins-jnlp -n jenkins

Belasse die restlichen Werte auf ihren Standardeinstellungen:

Teste die Verbindung mit dem “Test Connection”-Button.
Pod- und Container-Templates hinzufügen
Konfiguriere das Pod-Template wie folgt:
Pod Template:
- Name: jnlp
- Usage: Use this node as much as possible

Für dieses Tutorial verwenden die Agent-Container das jenkins/jnlp-agent-alpine-Image:
- Name: jnlp
- Docker image: jenkins/jnlp-agent-alpine

Füge ein HostPath-Volume hinzu:

- Host path: /var/run/docker.sock
- Mount path: /var/run/docker.sock

Füge ein EmptyDir-Volume hinzu:

- Mount path: /home/jenkins/agent

Speichere die Konfiguration.
Konfiguriere schließlich Jenkins so, dass nur Agent-Nodes Build-Jobs ausführen:
- Manage Jenkins
- Manage Nodes and Clouds
- master
- Configure
Setze:
- Number of executors: 0
- Usage: Only build jobs with label expressions matching this node

Speichern.
Die Pod-Build-Agents testen
Löse beide Build-Jobs gleichzeitig aus. Du solltest zwei Pods unter “Build Executor Status” sehen.

Wenn die Pods laufen, werden die Jobs darin ausgeführt:
