Dieser Blog-Beitrag ist eine Fortsetzung der Fallstudie zur Optimierung der CI/CD für einen Anbieter von Infrastrukturlösungen. Wir werden das Vorgehen zur Optimierung unserer Jenkins-Pipelines mithilfe gemeinsamer Bibliotheken erläutern und Beispiele für einen einfachen Maven+Podman-Build bereitstellen.
Obwohl wir uns in diesem Beitrag auf deklarative Pipelines konzentrieren werden, sollten Sie im Hinterkopf behalten, dass sowohl deklarative als auch skriptbasierte Pipelines von gemeinsamen Bibliotheken profitieren können. Die meisten hier behandelten Konzepte werden auch auf skriptbasierte Pipelines anwendbar sein, allerdings gibt es in einigen Fällen Unterschiede.
Vorteile der Verwendung gemeinsamer Bibliotheken
Die Verwendung gemeinsamer Bibliotheken in Jenkins bringt mehrere Vorteile mit sich, ähnlich wie bei der Verwendung von Bibliotheken für andere Programmiersprachen. Hier haben wir fünf Hauptvorteile hervorgehoben:
- Code-Wiederverwendung: Oftmals ähneln sich Pipelines, die über mehrere Jobs geschrieben sind, fast identisch, wobei der einzige wirkliche Unterschied ein paar Variablen wie Projektname oder Version sind. Mit einer gemeinsamen Bibliothek können wir denselben Code verwenden und unnötige Redundanz beseitigen.
- Einfachere Wartung: Dies steht im Zusammenhang mit dem vorherigen Punkt, da die Zentralisierung des Codes in einer gemeinsamen Bibliothek Codeänderungen schneller und einfacher macht. Jobs ziehen regelmäßig Änderungen aus der Bibliothek, alternativ können Sie die Bibliothek so einstellen, dass sie den aktualisierten Code automatisch für jeden Build abruft und unsere Änderungen sofort überträgt.
- Standardisierung: Gemeinsame Bibliotheken erleichtern die Durchsetzung besserer Codierungsstandards, sodass wir eine standardisierte Benutzeroberfläche für die Konfiguration von Jobs implementieren, Qualitätsprüfungen durchführen und verschiedene andere Aufgaben ohne erschwerte Konfiguration einzelner Jobs umsetzen können.
- Sicherere Jobs: Mit einer gut durchdachten gemeinsamen Bibliothek können wir alle notwendigen Überprüfungen für Eingaben implementieren, um potenzielle Sicherheitslücken zu vermeiden, bei der Fehlerbehebung zu unterstützen oder sich von bestimmten Fehlern zu erholen.
- Optimierter Pipeline-Code: Durch eine gemeinsame Bibliothek, die die inneren Abläufe verschiedener Funktionen in unserem Code abstrahiert, können wir eine hohe Komplexität in unseren Pipelines haben und gleichzeitig nur eine optimierte Schnittstelle für den Build-Ingenieur freigeben.
Voraussetzung
Für unsere Beispielimplementierung verwenden wir drei verschiedene Programmiersprachen (Java, Rust und Go), die auf 12 Jobs verteilt sind. Jeder Job erfordert, dass alle Schritte separat geschrieben werden; Code abrufen, Tests ausführen, erstellen usw. Die meisten dieser Schritte verwenden viel Code wieder, selbst wenn für verschiedene Sprachen erstellt wird.
Aus Gründen der Einfachheit lassen wir Parameter weg und werden nur die folgenden Phasen einbeziehen:
- Code abrufen (git)
- Erstellen (Maven)
- Container erstellen (Podman)
- Container in Registry verschieben (firmeninterne Registry)
Hier ist ein Beispiel für diese einfache Pipeline:
Link zum Code
Sie werden feststellen, dass alle unsere Variablen bereits in den Umgebungsblock exportiert wurden, während der größte Teil des Codes im Stages-Block sicher in eine gemeinsam genutzte Bibliothek verschoben werden kann. Von dort aus können wir es einfach aus der Pipeline aufrufen.
Umsetzung
Zunächst fügen wir unsere gemeinsame Bibliothek zu Jenkins hinzu, damit wir sie in unseren Pipelines aufrufen können. (Sie benötigen Administratorzugriff, um dies auf Ihrem Jenkins-Controller zu konfigurieren.)
- Navigieren Sie zu Ihrem Jenkins-Dashboard und klicken Sie auf der linken Seite auf „Jenkins verwalten“, wählen Sie dann „System“ aus, oder Sie können direkt zu diesem Pfad navigieren: /manage/configure
- Scrollen Sie nach unten zu „Globale Pipeline-Bibliotheken“ und klicken Sie auf die Schaltfläche „Hinzufügen“.
- Füllen Sie alle erforderlichen Parameter aus. Beachten Sie bitte, dass für gemeinsame Bibliotheken die Verwendung eines SCM wie Git erforderlich ist.
Wir empfehlen auch, „Frisches Klonsystem pro Build“ während des Tests zu aktivieren, damit Änderungen an der Bibliothek sofort in Ihren Jobs reflektiert werden.
In unserem Beispiel haben wir uns außerdem dafür entschieden, Hash Maps zu verwenden, um unsere verschiedenen Optionen zu speichern. Wenn Sie jedoch beispielsweise Umgebungsvariablen verwenden möchten, können Sie das ebenfalls tun. Beachten Sie jedoch, dass Sie dann die Eingabe für Ihre Bibliotheksmethoden ändern müssten.