DevOps? Na, klar – wir haben schon lange eine Jenkins-Pipeline die unseren Code testet. Sprechen Sie dazu doch einfach mit Tobias, dem Leiter des Entwicklungsteams oder mit Annika von Team-Operations. Ja? – Naja … nicht ganz.
Diese oder ähnliche Aussagen begegnen uns im Arbeitsalltag immer wieder. In diesem Blog-Zweiteiler wollen wir einmal unsere Sicht auf das Thema DevOps darstellen und Ideen liefern, wie man vielleicht das ein oder andere Gedankenmuster durchbrechen oder Missverständnisse auflösen kann.
Was ist DevOps?
Der Begriff DevOps leitet sich aus der Kombination der Disziplinen „Development“ und „Operations“ ab. Mit „Development“ ist in aller Regel die Entwicklung eines Systems oder einer Software-Komponente gemeint. Viele denken dabei zunächst einmal an ein größeres Softwareprojekt, welches durch mehrere Entwickelnde vorangetrieben wird, ein größeres Problemfeld adressiert, eine Rest-API hat oder mit einer Datenbank spricht. Aber auch das 10-zeilige Bash-Skript, welches ein Datenbank-Backup überprüft oder automatisiert Ressourcen der Test-Umgebung aufräumt, will „entwickelt“ werden.
Der Begriff „Operations“ beschreibt die Disziplin, die eigens entwickelte oder extern zur Verfügung gestellte Software in Betrieb zu nehmen und dafür zu sorgen, dass dieses System nicht auseinanderfällt. Wie wir immer wieder hören, wird dieses Themengebiet eher als notwendiges Übel betrachtet. Klar, wer hat schon Lust, den monatlichen Datenbank-restore-Test durchzuführen, während andere das nächst-coolere Feature für die Software entwickeln dürfen.
Der Zyklus
Doch dann: zwei der Teammitglieder erklären sich heldenhaft dazu bereit, sich um den Betrieb der Infrastruktur und der entwickelten Software zu kümmern – das Operations-Team ist geboren.
Super, dann haben wir ja nun ein Dev- und ein Ops-Team. Dann lasst uns doch mal hineinschauen, was die Teams anhand des DevOps-Zyklus so zu tun haben.
Das Dev-Team kümmert sich um die linke Seite der Schleife. Sie planen, was als Nächstes zu tun ist, entwickeln die Software nach ihren Vorstellungen, schreiben Dokumentation, bauen das APT-Package und den Docker-Container, lassen ihr Skript zum Testen laufen.
Läuft? Läuft! Versionsnummer 2.26.4 angehängt, Pakete releast und kurz beim Ops-Team auf der rechten Seite angerufen, dass sie nun die nächste Version deployen können.
Nachdem das Ops-Team noch kurz diesen einen fehlerhaften Eintrag aus der Datenbank gelöscht hat, geht‘s los. Sie schnappen sich die neue Version und ihr Python-Skript, um alles in Produktion auszurollen. Die Datenbank-Migration ist durchgelaufen, die Konfiguration wurde angepasst, wie in der Dokumentation vom Dev-Team beschrieben – Licht, Action, Monitoring – Läuft? … läuft doch oder? – Ehm … ne, irgendwie startet der Service alle paar-Minuten neu und außerdem gibt es jetzt fünf neue fehlerhafte Datenbank-Einträge.
Nun ja, sowas passiert. Eigentlich passiert sowas den ganzen Tag und im Wesentlichen geht es bei DevOps genau darum.
Schnittstelle == Schwachstelle
In diesem Setup mit den zwei Teams gibt es mindestens zwei Schwachstellen, und zwar immer, wenn das eine Team Dinge an das andere Team übergeben muss.
An der ersten Stelle ist es das Dev-Team, welches detailliert beschreiben muss, was sie entwickelt oder geändert haben, was sie sich dabei gedacht haben und welche Feinheiten es bei der Inbetriebnahme zu beachten gibt.
Die zweite Stelle ist die Übergabe der Ergebnisse bzw. Probleme, welche bei der letzten Inbetriebnahme im letzten Zyklus entstanden sind. Das Ops-Team müsste einen Bericht von allen Mängeln, die ihnen aufgefallen sind, zurück in die Planungsphase des Dev-Teams geben. Anhand dieser Ergebnisse könnten nun die nächsten wichtigen Schritte geplant und entwickelt werden, um den Betrieb der Software sicherzustellen.
Diesen Schritt beobachten wir nur sehr selten in der Praxis. Was viel wahrscheinlicher ist, dass Probleme gar nicht erst angesprochen werden. Gründe dafür können sein, dass die Probleme noch gar nicht so spezifisch formuliert werden können oder weil sich das Ops-Team nicht bloßstellen will, vielleicht etwas „falsch“ gemacht oder das ganze Konstrukt noch nicht verstanden zu haben.
Im schlimmsten Fall sind die Personen aus dem Dev-Team diejenigen, die nicht die richtigen Dinge entwickelt und das Ops-Team diejenigen, welche nicht ausreichend Wissen zum „eigenen Produkt“ oder dem „eigenen Service“ haben. Man spricht hier von der “Wall of Confusion”. Beide Teams versuchen das in ihren Augen “Richtige“ zu tun, haben aber eigentlich keine Idee, was auf der anderen Seite der Wand bei dem anderen Team vor sich geht. Die Situation wird zudem von einem meist unausgesprochenen Interessenkonflikt begleitet. Während das Dev-Team stetig neu entwickelte Features in Produktion schieben möchte, möchte das Ops-Team eigentlich nur einen stabilen Betrieb der Software gewährleisten, was durch jede neue Version oder jede Änderung am Setup schwieriger wird.
Damit dieses Setup funktionieren kann, muss ein großer, transparenter und ehrlicher Wissenstransfer in beiden Richtungen stattfinden. Dies führt in der Regel eher zu zwei Flaschenhälsen in besagtem DevOps-Zyklus und erhöht somit die Dauer von der Planung bis zur erfolgreichen Inbetriebnahme eines Fixes oder Features. Nach der “Theory of Constraints“ kann die Prozesskette des DevOps-Zyklus nur so schnell durchlaufen werden, wie es der langsamste bzw. ineffizienteste Schritt zulässt.
Das Dev-Team auf der Überholspur
Problematisch wird es , wenn sogar gar kein richtiges Release-Management stattfindet und Änderungen halbgar in Betrieb genommen werden sollen. Wiederholt sich der Zyklus, ohne dass das Ops-Team vollständig mit dem Deployment hinterhergekommen ist, summiert sich die Arbeit auf Seite des Ops-Teams immer weiter auf, während das Dev-Team hoch motiviert neue Features nachlegt. Dieses Ungleichgewicht kann dann dazu führen, dass der Abstand zwischen der entwickelten und der betriebenen Version immer größer wird. Es findet also Entwicklungsarbeit statt, die es im schlimmsten Fall nicht in die Produktion schafft, bevor das Feature vielleicht sogar schon wieder obsolet wird.
Was können wir also tun, um diesen Umstand aufzuheben? Dies beschreiben wir in Teil 2.