Vor- und Nachteile der Implementierung von Jenkins-Pipelines
Sofus Albertsen
Sofus is a Continuous Delivery Trainer and Consultant in Copenhagen. Before joining Eficode Praqma he was assistant professor on an Applied Science Bachelor program. He flies kites and in the summer he escapes the modern world by spending two weeks in a beach hut without electricity or network coverage.
Mit Multibranch-Pipelines ist Jenkins in den Wettbewerb der CI/CD-Server der nächsten Generation eingestiegen. Doch mit Konkurrenten wie Concourse und CircleCI gibt es keinen klaren Gewinner.
Praqma arbeitet seit fast einem Jahrzehnt mit Jenkins (früher Hudson), dem de-facto-Server für Continuous Integration. Lange Zeit war die führende Position von Jenkins unangefochten. Doch in letzter Zeit sind zahlreiche Wettbewerber auf den Plan getreten und machen dem guten alten Jenkins das Leben schwer. Als Gegenmaßnahme hat Jenkins Pipelines eingeführt: eine Groovy-DSL, mit der sich der CI-Ablauf per Code steuern lässt. Da CloudBees stark in Pipelines investiert, sind sie zur Zukunft von Jenkins geworden. Falls ihr sie euch noch nicht angesehen habt, besucht die Jenkins-Pipeline-Seite.
Solltet ihr also einfach alle eure Jobs in Pipelines umwandeln und danach glücklich bis ans Ende eurer Tage leben? Die Antwort lautet, wie bei fast allen anderen Dingen im Leben: Es kommt darauf an.
Dieser Beitrag zeigt Beispiele mit Phlow und Praqmas Pretested Integration Plugin. Wenn ihr es nicht kennt, informiert euch darüber.
Die Ausgangslage
Bei einem unserer Kunden wollten wir eine Pipeline erstellen, die parallel auf mehreren Betriebssystemen baut. Die Lösung sollte den Integrationsjob blockieren, bis alle Kompilierungen und Unit-Tests abgeschlossen waren. Die ursprüngliche Pipeline wurde über die Jenkins-UI erstellt, daher mussten wir sie irgendwie als Code umsetzen. Kein Herumgeklicke mehr!
Wir konnten entweder die bestehende Lösung in JobDSL umwandeln oder versuchen, denselben Build-Ablauf als Jenkins-Pipeline umzusetzen. Wir entschieden uns für Jenkins-Pipelines, um einige der Vorteile aus unserem Foliensatz zu zukünftigen Pipelines zu nutzen.
Multibranch oder nicht Multibranch – das ist hier die Frage!
Pipeline-Jobs gibt es in zwei Varianten: normal und Multibranch. Beide verwenden dieselbe Sprache: eine auf Groovy basierende DSL.
Wir entschieden uns für die Multibranch-Pipeline, da sich damit die Pipeline als Code im selben Repository hinterlegen lässt (Anwendungsfall Nr. 1 im oben genannten Foliensatz). Außerdem lässt sich bei einer Standard-Pipeline nicht erkennen, welcher Branch den Build ausgelöst hat, da Jenkins einen SHA und keinen Branch auscheckt.
Ein vereinfachtes Beispiel der produktiv eingesetzten Pipeline findet ihr hier.
So implementiert ihr Phlow in einer Pipeline
Da Praqmas aktuelle Version des Pretested Integration Plugin nicht mit Pipelines kompatibel ist, mussten wir die gleiche Funktionalität per Skript umsetzen. Ich werde nicht auf das Pipeline-Skript eingehen, sondern die Probleme erläutern, auf die wir bei seiner Entwicklung gestoßen sind.
Git Publisher gefällig?
Da Pipelines eine neue Art der Interaktion mit Jenkins sind, könnt ihr nicht alle Plugins und Funktionen nutzen, die ein normaler Freestyle-Job bietet.
Die Git-Checkout-Routine lässt sich beispielsweise für das Klonen bei der Pretested Integration verwenden. Wenn wir den Code jedoch wieder in einen Branch pushen müssen, gibt es keine Unterstützung.
Dazu wurde ein Issue erstellt. Bis es gelöst ist, müsst ihr reine Git-Befehle verwenden, die im sshagent-Plugin gekapselt sind.
Die Übersicht ist tot, lang lebe die Übersicht
Wie unten dargestellt, lassen sich die alten Freestyle-Jobs einfach zu einer Übersicht zusammenfassen, wenn sie so konfiguriert sind, dass sie einander auslösen.
Die Übersicht zeigt auf einen Blick, welcher Branch gerade gebaut wird. Außerdem könnt ihr wiederkehrende Fehler in einer Pipeline erkennen, indem ihr durch die Liste der Ausführungen scrollt.
Mit Jenkins Pipeline geht die Ansicht pro Master verloren, die wir mit PIP und Freestyle-Jobs nutzen können. Die Übersicht ist repositoryzentriert, das heißt, alle Branches werden gleich behandelt und erscheinen in einer gemeinsamen Ansicht. So befinden sich beispielsweise master und /version_2.x/master nun in derselben Ansicht.
Beim Öffnen eines einzelnen Builds erhalten wir eine deutlich bessere Übersicht über parallele Builds und eine einfachere Navigation zur relevanten Ausgabe als in der alten Übersicht. Jedes Symbol ist anklickbar und zeigt die Liste der Befehle sowie die entsprechenden Logs an.
Wenn dies also eine unverzichtbare Funktion ist, müsst ihr eine Art Dashboard erstellen, das einige der gleichen Informationen wie die alte Lösung bereitstellt (siehe dashing.io oder Pipeline Aggregator View).
Eine weitere Möglichkeit besteht darin, die Pipeline in zwei Teile aufzuteilen:
Einer ermittelt, ob die Pretested Integration erfolgreich war oder nicht.
Eine zum Aufbau der Master-Pipeline (alles nach dem Mauttor, das in unserer CoDe Storyline beschrieben wird)
So bekommt ihr die gewünschte Aufteilung pro Master, opfert dafür aber die vollständige Nachverfolgbarkeit anhand von Entwickler-Commits.
Ein deleteDir() am Tag hält den Doktor fern
Sofern nicht mehrere Stages gleichzeitig auf demselben Node laufen, bekommt ihr keinen neuen Workspace. Der alte wird automatisch wiederverwendet.
Das führt zu einer Menge deleteDir() in eurer Pipeline. Andernfalls treten beim Stashing und Unstashing seltsame Fehler auf.
Ihr könnt euren Node in eine Funktion kapseln, um sicherzustellen, dass ihr immer einen sauberen Workspace habt.
Beginnen wir von vorn
Das erneute Auslösen einer Pipeline aus einem bestimmten Job heraus ist bei Freestyle-Jobs ebenfalls einfach.
Wenn wir alles in einzelne Jobs aufteilen, können wir eine bestimmte Pipeline ab einem festgelegten Punkt erneut auslösen.
Bei Jenkins Pipeline gilt alles oder nichts. Ein erneutes Auslösen mit PIP ist damit nicht möglich, da ihr den Integrationsschritt nicht erneut auslösen möchtet.
CloudBees hat ein proprietäres Plugin namens Checkpoints entwickelt. Damit könnt ihr an diesem Checkpoint neu starten. Leider wurde es weder als Open Source veröffentlicht, noch wurden Issues, die darauf hinweisen, geschlossen.
Das spricht ebenfalls dafür, die Pipeline in zwei Teile aufzuteilen: einen für die Integration in Master und einen für die Build-Pipeline selbst.
Manuelle kleine Schritte mit Fallstricken
Wenn ihr vor dem Übergang zur nächsten Stage in eurer Pipeline eine manuelle Validierung durchführen müsst, verwendet das Tag input in eurem Jenkinsfile. Wenn es nur ein Signal ist, führt es auf einem Flyweight-Executor aus, damit es keinen Executor-Slot auf einem Node belegt.
stage 'Promotion' { input 'Deploy to Production?' }Dieser Workflow hat einige Nachteile. In der Jenkins-UI sieht es so aus, als würde die Pipeline noch ausgeführt, obwohl sie auf eine manuelle Eingabe wartet. Ich hätte sie lieber als angehalten statt weiterhin aktiv laufend gesehen. Aber das ist derzeit der Stand.
Fazit
Jenkins Pipelines sind definitiv ein Schritt in die richtige Richtung, und ich muss ganz ehrlich sein: Ich mag sie, sehe aber auch Probleme!
Erst vor etwas mehr als einem Monat hat Jenkins das Label „BETA“ von Blue Ocean entfernt, der neuen UI für Pipelines.
Einige der hier beschriebenen Probleme könnten in einem Jahr gelöst sein, und mit manchen Dingen lernen wir einfach, auf elegantere Weise umzugehen.
Zusammenfassend findet ihr hier eine TL;DR-Übersicht der oben erläuterten Vor- und Nachteile:
Vorteile:
Die Möglichkeit, die Pipeline in eurem SCM-Repository zu definieren: Pipeline as Code!
Eine neue Pipeline ist einfach ein neuer Branch – und ihr könnt loslegen.
Eure Pipeline wird nicht nur wie Code behandelt, sie ist Code!
Stashing stellt sicher, dass parallele Builds denselben Code ausführen.
Pipelines sind die Zukunft von Jenkins. Passt euch wie die Besten an – oder geht unter wie der Rest.
Nachteile:
Kein Pretested Integration Plugin verfügbar
Die Git-SCM-Funktionalität ist auf grundlegende Git-Befehle beschränkt
Kein Überblick für Manager, wenn die Pipeline vollständig ist
Kein Überblick für Entwickler, wenn die Pipeline in zwei Teile geteilt ist.
Keine Möglichkeit, Teile der Pipeline erneut auszuführen
/ready-Branches werden nach ihrer Ausführung (und dem Merge) aus der Übersicht gelöscht
- CI/CD
Subscribe to our newsletter
Related blogs