DevOps – Die Welt von CI/CD (Teil 1)

David Jun 26, 2018
DevOps – Die Welt von CI/CD (Teil 1)

Mit kontinuierlicher Integration (Continuous Integration, CI) und kontinuierlicher Bereitstellung (Continuous Delivery, CD) können Software-Engineers ihren Kunden viel häufiger und zuverlässiger einen Mehrwert bieten.

Dies erklärt man am besten, indem man sich zunächst eine Welt ohne CI/CD vorstellt.

Was soll das? Eine Welt ohne CI/CD?

DevOps_Grafik

 

 

 

 

 

 

Lernen Sie Reto kennen, DevOps Engineer bei DevOps Ready. Reto arbeitet seit vier Wochen an einer neuen Funktion. Auf seinem eigenen Gerät funktioniert sie soweit und er möchte sie seinen Kunden anbieten. Der Veröffentlichungsprozess bei DevOps Ready läuft wie folgt ab:

  1. Man veröffentlicht die neue Funktion auf einem Testserver.
  2. Man lässt einen anderen Mitarbeiter die neue Funktion zu Qualitätssicherungszwecken prüfen.
    1. Es ist schon vorgekommen, dass manche Veröffentlichungen den Kunden Probleme bereitet haben. Vor jeder Veröffentlichung auf dem Wiki muss jetzt für jede Anwendung eine Liste mit wichtigen Qualitätskontrollen durchgegangen werden.
  3. Man stellt die Funktion den Kunden bereit, sobald die Qualitätssicherung (Quality Assurance) sie validiert hat.
  4. Bei Problem macht man die Funktion schnellstmöglich rückgängig.

Retos Abteilung kümmert sich um einige Webanwendungen. Wenn er und sein Team also davon sprechen, dass sie eine neue Funktion bereitstellen, meinen sie damit die Übertragung der Anwendung per FTP an die Server. Die Änderungen rückgängig zu machen impliziert auch eine Wiederherstellung der letzten funktionierenden Version auf dem Server.

Probleme bei diesem Ansatz 

Probleme können zwei Bereiche betreffen: Qualitätssicherung und Bereitstellung.

Qualitätssicherung

Reto arbeitet seit vier Wochen an einer neuen Funktion. Auf seinem eigenen Gerät funktioniert alles soweit.

Reto kann die Funktion, an der er arbeitet, leicht testen, aber kann er sich sicher sein, dass die Anwendung insgesamt läuft?

 Er könnte sich händisch durch die gesamte Seite klicken, wenn diese klein genug ist, und prüfen, ob „alles okay aussieht“. 

Wenn nun die Codebasis aber aus Zehntausenden von Codezeilen besteht? Wie soll man herausfinden, ob die Änderung die Anwendung nicht an irgendeiner Stelle unbrauchbar macht?

Vor jeder Veröffentlichung auf dem Wiki muss jetzt für jede Anwendung eine Liste mit wichtigen Qualitätskontrollen durchgegangen werden.

Wer pflegt diese Liste? Wer aktualisiert sie und wann? Wie kann man sicherstellen, dass die Tests tatsächlich durchgeführt wurden?

Was ist, wenn die Prüfliste über 30 Punkte umfasst? Wir müssen immer wieder alle Punkte bei jeder Veröffentlichung durcharbeiten.

Weitere Gedanken

Es ist mit Sicherheit alles andere als ein Vergnügen, diese Qualitätssicherungsaufgaben übernehmen zu dürfen. Steckt ein kleiner Bug in Reto's Funktion, muss er den gesamten Prozess noch einmal durchgehen.

Zudem wächst die Qualitätssicherungsliste sicherlich mit dem Code.

Bereitstellung

Die neue Funktion auf einem Testserver veröffentlichen

Der Prozess ist bei jeder Veröffentlichung gleich: Code auschecken, in einem bestimmten Ordner ablegen, Datenbankänderungen vornehmen, den Webserver neu starten.

Eine Liste der Schritte sollte stets an einem für alle Ingenieure offensichtlichen Ort vorliegen (besonders sinnvoll für neue Mitarbeiter), was aufwendig und bald überholt ist.

Und wie wird sichergestellt, dass man nicht händisch einen notwendigen Schritt vornimmt, den man nicht in der Liste vermerkt und diesen dann bei der nächsten Bereitstellung natürlich vergisst, wodurch diese misslingt?

Die Funktion den Kunden bereitstellen, sobald die Qualitätssicherung sie validiert hat

Hier wiederholt sich der obige Prozess: Veröffentlichungen auf Test- oder Kundenservern sollten genau gleich ablaufen.

Die Funktion bei Problemen schnellstmöglich zurückziehen

Das Rückgängigmachen eines Codes sollte auch jedes Mal genau gleich erfolgen, egal welche Funktion oder Bug-Behebung wir entfernen wollen.

Was ist also zu tun? Einfach alles automatisieren!

Die Prinzipien von DevOps schreiben kurze Feedback-Zyklen vor. In DevOps Ready ist es schwer, Funktionen häufig und zuverlässig zu veröffentlichen: Wahrscheinlich trifft nur eines von beidem zu.

Glücklicherweise gibt es Automatisierungsprinzipien, die uns bei den meisten der oben genannten Einwände helfen können.

Automatisiertes Testen

Jeder Code ist schuldig, bis seine Unschuld bewiesen ist. – Anonym

Händische Tests werden bei einer Anwendung von Menschen durchgeführt.
Automatisierte Tests werden bei einer Anwendung von einem Computer durchgeführt.

Mit beiden Verfahren wird geprüft, ob eine Anwendung richtig funktioniert. Allerdings haben automatisierte Tests einen bedeutenden Vorteil: Man kann ohne menschliche Interaktion und Umschweife beliebig häufig prüfen, ob eine Anwendung funktioniert. Computer langweilen sich nie! Es wäre mit grossem Aufwand für den Tester verbunden, bei jeder neuen Veröffentlichung händisch zu testen, ob die gesamte Anwendung funktioniert.

Mit automatisierten Tests kann man leichter sehen, ob eine Funktion auch in einem Jahr noch richtig funktioniert.

Eine Frage ist allerdings noch offen: Wann soll man diese Tests durchführen? Entwickler können (und sollten) sie bei der Entwicklung durchführen. Aber was macht man, wenn sie es vergessen?

Hier kommt die kontinuierliche Integration ins Spiel.

Kontinuierliche Integration

Mit der kontinuierlichen Integration wird sichergestellt, dass eine Funktion oder Bug-Behebung eines Engineers nicht die restliche Anwendung beschädigt (wobei natürlich automatisierte Tests für die Anwendung vorhanden sein müssen). Das heisst, sie prüft, ob ein neuer Code mit der bestehenden Anwendung kompatibel ist.

Immer wenn ein neuer Code zur Anwendung hinzugefügt wird (üblicherweise als Pull/Merge-Request), lässt man sich vom CI-Server bestätigen, dass die App voll funktionsfähig ist. Ist sie es nicht, lässt man es nicht zu, dass der Code in den Master-Branch eingebunden wird. Stellt man später fest, dass die eingebundene Funktion nach wie vor Probleme macht, wird sie nicht bereitgestellt. 

Einige CI-Lösungen: TravisCI, CircleCI, Gitlab, usw.

Kontinuierliche Bereitstellung

Dank CI kann man sich jetzt sicher sein, dass eine Anwendung wunschgemäss funktioniert. Aber wie zeigt man sie seinen Kunden? Und kann man diese Änderungen schnell genug rückgängig machen, wenn etwas in der Produktion schiefläuft?

Zeit für die kontinuierliche Bereitstellung!

Hier geht es um etwas ganz Einfaches: Man sollte eine Anwendung in nicht mehr als einem Schritt in einer Umgebung (Staging/Produktion) bereitstellen können, sei es ein Git-Push, ein Mausklick, eine Slack-Message an einen Bot oder ein Tool in der Befehlszeile etc. Hierfür sind mehrere Tools verfügbar.

Capistrano ist das Standard-Tool für die Bereitstellung eines Codes auf einem Host (zumindest in der Ruby-Community).

Wenn man Container und ein System zur Container-Orchestrierung (Kubernetes, Openshift etc.) nutzt, ist der Bereitstellungsprozess standardmässig bereits verschlankt.

Einige CI/CD-Lösungen: Codeship, Gitlab, Kubernetes, Openshift, usw.

Zusammenfassung

Laut dem 2017 State of DevOps Report von Puppet schaffen leistungsstarke Teams Folgendes:

  • Sie stellen 46-mal häufiger Codes bereit als weniger leistungsstarke Teams.
  • Sie haben 440-mal kürzere Vorlaufzeiten vom Commit bis zur Bereitstellung als weniger leistungsstarke Teams.

  • Sie haben eine durchschnittlich 96-mal schnellere Wiederherstellung nach Ausfällen als weniger leistungsstarke Teams.

  • Sie haben eine fünfmal geringere Fehlerrate bei Änderungen.

CI/CD zählen zu den besten Praktiken von DevOps, die solche leistungsstarken Teams ausmachen.

Noch einmal in aller Kürze: Mit automatisiertem Testen lässt sich am besten sicherstellen, dass eine Anwendung richtig funktioniert.

Mit kontinuierlicher Integration kann man herausfinden, ob eine App generell funktionsfähig ist und insbesondere ob eine neue Funktion die bestehende Codebasis beschädigt.

Mit kontinuierlicher Bereitstellung kann man seinen Kunden häufig einen Mehrwert bieten.

Was steht an?

Teil 2 dieser CI/CD-Serie von DevOps befasst sich mit dem Aufbau einer richtigen CI/CD-Pipeline: Bleiben Sie dran!


Docker ist ein Tool, das den DevOps-Ansatz unterstützt. In dieser Videopräsentation von unserem TechTalkThursday im März sprach David über "Docker for Developers" und nutzte die nine Status-App als Beispiel für die Transition zu einem Docker-Setup im Detail.

Jetzt Video-Präsentation anschauen