One ticket: your access to two conferences

One Click Deployment – Automatisiertes Testen in der Pipeline

One Click Deployment – Automatisiertes Testen in der Pipeline

Ein Beispiel aus der Praxis

 

Ausgangslage
In unserem Beispiel gehen wir von folgender Ausgangslage aus: In einem Projekt gibt es diverse unabhängige Services, die jeweils ihre eigenen Release-Zyklen haben. Der Kunde möchte nun diese Services miteinander verbinden und automatisieren, um die manuellen Prozesse und die Lead Time zu minimieren. Dies führt zu einer Microservice-Architektur mit vielen kleinen Services, die unabhängig voneinander getestet und deployed werden müssen.

 

 

 

 

Abbildung 1: Ausgangslage (Quelle: adesso)

Evaluation Prozess/Tools
Gemeinsam mit dem Kunden haben wir uns aufgrund der Anforderungen an das System, den Bedürfnissen an den Release Prozess und des vorhandenen Know-Hows des Teams, für Continous Delivery entschieden.

Continuous Delivery ist die Weiterführung von Continuous Integration, mit dem Ziel, das Deployment mit sehr geringem Risiko und zu jeder Zeit mit lediglich einem Knopfdruck auszuführen. Der Master ist dabei immer in einem Zustand, in dem er released werden könnte. Fehler, die im Master gefunden werden, haben die höchste Priorität und müssen sofort behoben werden. Dies entspricht im Grunde dem Andon-Cord von Toyota.

 

 

 

 

 

Abbildung 2: Continuous Delivery (Quelle: adesso)

Exkurs: Andon-Cord

Das Andon-Cord ist Bestandteil des Toyota-Produktionssystems. Es ist eine physische Reissleine, welche von jedem Mitarbeiter zu jeder Zeit betätigt werden kann. Das ziehen des Andon-Cord hat den sofortigen Anlagenstopp zur Folge. Die Produktionsanlage wird erst wieder gestartet wenn der Fehler behoben wurde. Somit sind alle Mitarbeiter bis zur Lösung des Problems blockiert, was eine schnelle Problemlösung bewirkt und somit die Lead Time verkürzt.

 

Lead Time

 

 

 

 

 

Abbildung 3: Lead Time (Quelle: adesso)

Die Lead Time ist die Zeit, die benötigt wird, um vom Zeitpunkt an dem man eine Aufgabe erhält (a) zum Punkt gelangt, an dem die Aufgabe erfolgreich dem Kunden ausgeliefert wird. Oder anders ausgedrückt: die Zeit von der Erstellung des Jira Tickets bis zum Deployment in Produktion. Der blaue Pfeil (b) kennzeichnet den Zeitpunkt, an dem mit der Implementation begonnen wird. Der gelbe Pfeil (c) signalisiert, wann das Artefakt bereit zur Auslieferung ist. Der blaue Bereich (2) ist somit die Process Time. Die Zeit davor (1) und die Zeit danach (2) wird gewartet. Die Wichtigkeit einer geringen Lead Time erkannte Eliyahu M. Goldratt schon im Jahre 1984, als er sein Buch „The Goal“ veröffentlichte

Die Anforderungen an Continuous Delivery wurden technisch mit Jenkins Pipelines umgesetzt. Jenkins ist sehr verbreitet und bietet daher eine grosse Community, die sehr schnell und zuverlässig bei Problemen hilft. Zudem hat das Team schon viel Erfahrung mit Jenkins in vorherigen Projekten sammeln können.

Eine Jenkins Pipeline besteht aus mehreren Stages, wobei ein Stage aus mehreren einzelnen Anweisungen besteht. Hier sind dem Team keinerlei Grenzen gesetzt und es können beliebige Shell- oder Batch-Befehle abgesetzt werden, die wiederum in einem Stage zu einem logischen Prozess-Schritt zusammengefasst werden.

 

 

 

 

 

Abbildung 4: Stages einer Pipeline (Quelle: adesso)

Dieser Ausschnitt einer Pipeline enthält die Stages: build and test, undeploy on dev, deploy on dev, system tests und continue on test.

Implementation

Pipeline

 

 

 

 

 

Abbildung 5: Pipeline mit mehreren Builds (Quelle: adesso)

Die Stages der Development-Umgebung werden direkt nach dem Start automatisch sequentiell ausgeführt. Schlägt ein Stage fehl, wird die Pipeline sofort angehalten und ist im Zustand <<failed>> (Fehlgeschlagen). Bis dieser Fehler behoben ist, sind alle nun folgenden Umgebungen für jegliche Deployments gesperrt – nach dem Prinzip der oben beschriebenen Andon-Cord.

 

 

 

Abbildung 6: Fehlgeschlagener Build (Quelle: adesso)

Um etwas in Produktion zu ändern, muss immer die gesamte Pipeline durchlaufen werden. Dadurch weiss jedes Teammitglied immer ganz genau was auf welcher Umgebung installiert ist. Zudem ist garantiert, dass die Qualität genau den Anforderungen an die entsprechende Umgebung entspricht.

Bevor eine Version auf die nächste Umgebung installiert wird, wartet die Pipeline auf eine manuelle Freigabe durch einen berechtigten Benutzer. Möchte man diese Version noch nicht auf der nächsten Umgebung installieren, ist es durchaus legitim die Pipeline zu diesem Zeitpunkt abzubrechen und auf eine neue Version zu warten.

 

 

 

Abbildung 7: Abgebrochener Build (Quelle: adesso)

Ausblick

Last Tests

Um die Feedback-Zyklen noch weiter zu verkürzen, sollte man versuchen, so viel wie möglich zu automatisieren. Momentan müssen Last Tests im unserem Beispiel-Projekt manuell gemacht werden, was mühsam ist und viel Zeit in Anspruch nimmt. Um dies zu vermeiden, könnte man beispielsweise JMeter Last Tests erstellen, welche jeweils automatisch nach den System Tests ausgeführt werden.

Exkurs: JMeter

JMeter ist ein in Java geschriebenes Tool für das Ausführen von Last Tests.

http://jmeter.apache.org/

Consumer Driven Contract Tests

In einer Microservice-Architektur ergibt sich oft die Situation, dass sich verschiedene Parteien auf eine Schnittstelle einigen müssen, die dann von diversen anderen Services konsumiert wird. Dies hat zur Folge, dass bei Anpassungen dieser Schnittstellen viel Kommunikationsaufwand zwischen den einzelnen Teams notwendig wird. Um dies auf ein Minimum zu reduzieren, gibt es die Möglichkeit von Consumer Driven Contract Tests. Dies sind im Grunde genommen weitere System Tests, die man zusätzlich in die Pipeline einbaut. Das Besondere an diesen Tests ist, dass jedes Team, das an demselben System mitarbeitet, Schreibrechte auf diesem Repository hat. Dadurch ist es jedem Team möglich, mit Hilfe von Tests zu definieren, wie das erwartete Verhalten der Schnittstelle aus ihrer Perspektive ist. Schlägt ein solcher Test fehl, muss das Team, das den Service besitzt entscheiden, ob es wirklich ein Fehler ist oder ob es Missverständnisse bei der Verwendung ihres Services gibt. Im zweiten Fall müssen die beiden Teams zusammensitzen und das Problem gemeinsam lösen. Bevor dies nicht der Fall ist, steht die Pipeline still und es kann keine Änderung mehr deployed werden.

Fazit

Um das Ziel von schnellen Feedback-Zyklen zu erreichen, haben wir an diversen Stellen Abhängigkeiten aufgelöst. Dies birgt jedoch auch Gefahren. Einem Team ist es dadurch sehr einfach möglich, sich zu verstecken. Legt niemand im Team Wert auf Qualität, ist das sehr schwer zu erkennen, da der Source Code von niemand anderem ausgechecked wird. Ein Indikator dafür könnte es sein, wenn ein Team sehr wenig mit anderen Teams kommuniziert. Üblicherweise tauscht man sich oft aus, da viele Anforderungen in anderen Services schon einmal umgesetzt wurden. Ausserdem profitieren die Teams untereinander von den bereits gemachten Erfahrungen. Stellt man fest, dass sich ein Team zurückzieht, empfehlen wir, dem Umstand mit teamübergreifenden Codereviews oder teamübergreifenden Pairprogramming entgegen zu wirken, um so mögliche Qualitäts-Probleme früh zu erkennen.

 

 

Autor

Robert Brem (robert.brem@adesso.ch): Robert Brem ist bei der adesso Schweiz AG im Bereich Technology Innovation tätig und hat darin die Verantwortung für alle DevOps Belange. Er berät und entwickelt in Kundenprojekten bei denen der Fokus auf Microservices liegt.

Robert Brem

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Lade...