#JCON2017 #ContinuousDelivery #RaspBerryPi

In diesem Artikel wird ein Ansatz für eine Continuous-Delivery-Pipeline vorgestellt, der aufzeigt welche Teilprozesse es gibt, um effektive Continuous-Delivery oder sogar Continuous-Deployment zu betreiben. Auch die Integration von Tools und Frameworks wird beleuchtet. Um zu demonstrieren, wie schlank und einfach eine solche Pipeline sein kann, wurde die gesamte Pipeline experimentell auf Raspberry-PIs aufgebaut, die in einen Koffer passen. Dieser Ansatz lässt sich auch nach Rechenzentrumsanforderung skalieren.

Veränderungen im Geschäftsmodell zwingen IT-Organisationen oder IT-Dienstleister in immer schnellere Release-Zyklen. Konzepte und Architekturen wie Hybrid-Cloud, Container und Microservices erhöhen die Komplexität der IT-Landschaft. Häufig sind klassische IT-Betriebs- Organisationen nicht schnell genug in der Lage, die gewünschte Unterstützung für den Geschäftsbetrieb zu liefern. Es sind grundlegende Änderungen an der Arbeitsweise notwendig, wie Software erstellt und geliefert wird.
Continuous-Integration (CI) ist eine grundlegende Praktik in der agilen Softwareentwicklung. CI beschreibt einen Prozess, bei dem die gesamte Codebasis regelmäßig und vollständig gebaut und getestet wird, um Feedback über die Integration neuer Anwendungskomponenten zu erhalten. Ziel ist dabei ganz klar, Fehler früher zu erkennen und leichter zu beheben, da jede (lokale) Änderung mit der gesamten Codebasis gebaut und getestet wird. Neben Modultests sollten in einem CI-Prozess auch weitere QS-Maßnahmen wie z.B. statische Codeanalyse eingebunden werden. Das Ergebnis von einem CI-Prozess sind fortlaufend gebaute und vor allem qualitätsgesicherte Artefakte, die jederzeit auf einem System installiert werden könnten.
Continuous-Delivery baut auf den CI-Prozessen auf. Das Ziel von Continuous-Delivery (CD) ist die Beschleunigung der Software-Lieferkette ab dem Punkt, an dem das Entwicklerteam die Arbeiten am Quellcode abgeschlossen hat, bis zum Zeitpunkt, ab dem die Software tatsächlich in Produktion läuft und vom Kunden genutzt werden kann. Erst dann kann die Software einen Wert generieren.
Continuous-Delivery ist das Zusammenspiel von Rollen, Prozessen und Werkzeugen, um dieses Ziel zu erreichen.
Während Continuous-Delivery die Software „nur“ laufend erstellt und auf den frühen Stufen wie Integration sowie der QA-Stage auch voll automatisiert ausliefert, kommt es nicht zu einem vollautomatisierten Deployment auf der Produktionsumgebung. Bevor etwas in Produktion installiert wird, sind weiterhin manuelle Freigaben und Genehmigungsschritte notwendig, die natürlich ebenfalls werkzeuggestützt ablaufen sollten (und nicht etwa über Excel „gesteuert“). Bei der Umsetzung von Continuous-Deployment entfallen diese manuellen Prozesse und der Commit des Quellcodes durch den Entwickler ist der letzte manuelle Vorgang in solch einer Pipeline.
Für unsere weiteren Betrachtungen spielt es keine große Rolle, ob die Pipeline Continuous-Delivery oder Continuous-Deployment realisiert, es können die gleichen Werkzeuge und Methoden genutzt werden – der Unterschied beruht im Wesentlichen auf dem weglassen manueller Genehmigungen.

Die Rolle des Release-Managements

Im klassischen Sinn besteht das Release-Management aus allem, was für die Umsetzung eines Release notwendig ist. Es fängt also an bei der Definition und zeitlichen sowie inhaltlichen Planung, geht über die Entwicklung und Qualitätssicherung und endet nach dem Deployment beim Monitoring und bei der Wartung.
Deployment und Release treten in etwa gleich häufig auf, und das ist kein Zufall. Denn Release bedeutet Freigabe, Freigabe in Produktion. Je nach (unter Umständen gesetzlichen) Anforderungen ist eine aufwendige Freigabeprozedur notwendig, inklusive der Sammlung von (digitalen) Unterschriften der Abnahmeberechtigten.

Release-Management ist vor allem dann sinnvoll, wenn ein komplexes Produkt aus mehreren Einheiten besteht, die unabhängig voneinander gebaut werden, aber zusammen geliefert werden müssen, weil Produkt A Schnittstellen von B verwendet, sich diese aber geändert haben. Produkt A kann entsprechend mit der älteren Version von B arbeiten. Natürlich gibt es Pattern und Vorgehensweisen um Einheiten technisch zu entkoppeln, z.B. mit Feature-Toggles. Dies kann aber sehr aufwändig sein und sollte gut überlegt werden.

Bestandteile einer einfachen CD-Pipeline

Auf den ersten Blick besteht eine minimale CD-Pipeline nur aus wenigen Komponenten:

  • ein Versionskontrollsystem wie Git oder Subversion,
  • ein CI-Server wie Jenkins, Bamboo, TeamCity o.ä.,
  • an den CI-Server angeschlossene Testwerkzeuge wie JUnit, Selenium usw.,
  • Codeanalyse mit Werkzeugen wie Sonar usw.,
  • eine Technologie zum Deployment, im einfachsten Fall selbstgeschriebene Skripte oder CI-Server Plugins,
  • eine oder mehrere Zielumgebungen, auf die installiert werden soll.

Schematisch sieht das wie in (Abb. 1) aus.

Bestandteile einer einfachen CD-Pipeline (Abb. 1)

Bestandteile einer einfachen CD-Pipeline (Abb. 1)

Im Prinzip fehlen uns jetzt nur noch die Werkzeuge zur Provisionierung (wie z.B. Ansible, Puppet und Chef, oder bei Container-Umgebungen ein Container-Orchestrator wie Kubernetes oder OpenShift) sowie die Tools zum Monitoring der Anwendungen in Produktion. Aber reicht das aus?

Erweiterte Anforderungen an eine CD-Pipeline

Sicher reichen solche einfachen Pipelines in einem projektbezogenen Kontext oder einem Softwarehaus aus, das nur ein Produkt vertreibt oder wenige Services anbietet. Wenn man aber in Unternehmenskategorien wie Banken, Versicherungen, Logistik, Automobilfirmen und deren Zulieferer oder Bundesbehörden darüber nachdenkt, kommen einige weitere Anforderungen dazu:

  • Sicherheit: Wer darf die Pipeline ändern, ergänzen, Release-Prozesse starten usw.?
  • Compliance und Nachweispflichten: Wer hat wann welches Release für die Produktion freigegeben? Welcher Build war überhaupt in dem Release und welche Anforderungen/User-Stories wurden darin umgesetzt? Wie sind die Tests in diesem Release gelaufen?
  • Release-übergreifende Abhängigkeiten: Was ist, wenn unser Produkt die Zulieferung eines anderen Produktes oder Services bedarf? Müssen wir dann warten oder können wir unser Release fortsetzen?
  • Zusammenarbeit mit Fachabteilung und Auftraggebern: Freigaben zwischen Master- und Sub-Releases, Koordination mit Marketing- und/oder Vertriebsaktivitäten.
  • Integration in Kollaborationswerkzeuge wie JIRA, Slack, HipChat usw. um eine Tool-übergreifende Kommunikation und Traceability zu erhalten.
  • Integration in IT-Service-Management-Landschaften, um Change-Getriebene Prozesse gemeinsam mit den agilen Methoden verwenden zu können.

Im Unternehmensumfeld erhalten wir also einen Blue-Print, der evtl. wie in (Abb. 2) aussehen kann.

Eine erweiterte CD-Pipeline und sinnvoll ergänzende Werkzeuge. (Abb. 2)

Eine erweiterte CD-Pipeline und sinnvoll ergänzende Werkzeuge. (Abb. 2)

Experiment und Setup

Soweit zur Theorie. Doch wie sieht es in der Praxis aus? Für unser Experiment haben wir folgende Anforderungen an unsere CD-Pipeline gestellt:

  • transportabel für Messen und Konferenzen,
  • offlinefähig (da man auf Veranstaltungen leider immer noch nicht überall ein Netzwerk vorfindet),
  • portabel und skalierbar (potentiell Cloud-fähig),
  • in eine Richtung steuern, welche für uns nicht alltäglich ist.

Basierend auf diesen Prämissen haben wir uns entschieden, unser Experiment folgendermaßen aufzubauen:

  • Hardware besteht ausschließlich aus Raspberry PI 3,
  • Alle verwendeten CD-Tools müssen in Docker-Containern lauffähig sein,
  • Es soll eine Mischung aus kommerziellen und Open-Source-Tools genutzt werden.

Es war uns bewusst, dass wir damit keine produktive Pipeline aufbauen können, da vor allem High-Availability der einzelnen Komponenten und zentrale Nutzerverwaltung über ein LDAP (Lightweight-Directory-Access-Protocol) nicht bearbeitet wurden. Wir haben die Tools aber so gewählt, dass bei einer Nutzung im Echtbetrieb diese Anforderungen umgesetzt werden könnten.

Die meisten CI/CD-Werkzeuge sind mittlerweile als Docker-Images verfügbar. Allerdings fast ausschließlich für x86-Systeme. Raspberry-Rechner besitzen aber nun mal einen ARM-Prozessor. Damit funktionieren dann Bibliotheken oder Programme nicht, die x86-Code enthalten und es bedarf einiger Änderungen an den Docker-Files.

Unsere CD-Pipeline besteht aus folgenden Werkzeugen:

  • Versionskontrolle: Git und RepoManager GitBlit. Die Wahl fiel auf GitBlit, weil es sehr schlank ist und dafür bereits ein fertiges ARM-Docker-Image verfügbar ist.
  • CI-Server: Jenkins, als Continuous-Integration-Werkzeug erlaubt es Projektteams sich auf ihre Arbeit zu fokussieren, indem es den Build-Prozess und das Artefaktmanagement automatisiert. Für Jenkins sprechen außerdem die zahlreich verfügbaren Plugins.
  • Artefakt-Repository: Artifactory.
  • Deployment Automation: XL-Deploy bietet eine modellbasierte Deployment-Lösung und damit eine hohe Skalierbarkeit, eine eingebaute Analyse über alle Aspekte von Deployments, unterstütz Agilität und hohe Sicherheitsstandards sowie Auditierungsmöglichkeiten
  • Release-Management und Orchestration: Mit XL-Release lassen sich Abhängigkeiten verwalten und Risiken in Release-Management-Prozessen verringern. Außerdem ermöglicht XL-Release die schrittweise Optimierung und Automatisierung der Release-Prozesse in einem kontinuierlichen Verbesserungsprozess. Dabei integriert es die vorgelagerten Entwicklungsprozesse durch Plugins für Jenkins, Artifactory, JIRA, Git/GitHub und andere Werkzeuge.
Die Umsetzung der Pipeline. (Abb. 3)

Die Umsetzung der Pipeline. (Abb. 3)

Fazit

Die Hauptarbeit bei der Realisierung des Setups war, stabile und aktuelle Raspberry-Basis-Images zu bekommen, die eine aktuelle JVM beinhalten und alle notwendigen nativen Bibliotheken mitbringen. Ein großes Problem war, eine aktuelle NodeJS-Version zu finden, die auf ARM läuft, da nativ das Meiste nur für x86 bereitgestellt wird. Überraschenderweise nutzte auch das Artefakt-Repository von Nexus native Bibliotheken, für die wir keine ARM-Variante fanden. JFrogs Artifactory lief hingegen problemlos auf ARM in einem Docker-Container.
Als Betriebssystem für unsere Raspberry-Rechner nutzen wir hypriot OS, welches eine lauffähige Umgebung für Docker mitbringt. Die Integration funktioniert hier sehr gut und das Hauptexperiment „Docker auf Raspberry“ war nicht durch das Setup von Docker geprägt, sondern von dem Erstellen der ARM-Images. Das Basis-Image rpi-java ist hierfür empfehlenswert.

asd

Matthias Zieger ist seit mehr als 20 Jahren in der IT-Industrie unterwegs mit den Themen Software-Entwicklung, Architektur, Application Lifecycle Management und DevOps u.a. für IBM, Borland, Microsoft und codecentric. Die letzten drei Jahre hilft er großen Unternehmen, ihre Software schneller in Produktion zu bringen mit den Release Management- und Deploymentlösungen von XebiaLabs – von klassischen Java-EE-Umgebungen über Docker und Cloud bis hin zu Serverless-Architekturen.


asd

Jan Rümenapf ist Java-Web-Entwickler im agilen Umfeld. Am liebsten baut er Anwendungen mithilfe des Spring-Frameworks. Derzeit arbeitet er sehr viel mit ReactJS und beschäftigt er sich mit Cloud Themen sowie der Testautomatisierung.


(Visited 66 times, 1 visits today)

Leave a Reply