Dev/GitOps @CAOS

[DE] Wie wir Dev/Git Ops bei CAOS verstehen und leben

Dev/GitOps @CAOS image

Die Problemstellung

Zusammenarbeit und Kommunikation

Der Klassiker nach Retrospektiven Meetings und Software Projekt reviews: “Wir müssen besser zusammenarbeiten und an unserer Kommunikation arbeiten”. In Lehrbüchern steht auch gerne das “Informationen zur richtigen Zeit, am richtigen Ort, den richtigen Personen zur Verfügung gestellt werden müssen”. Dazu kommen teils unterschiedliche Interessen. So möchte ein Product Owner seine Features in kürzester Zeit, ein Entwickler die bestmögliche (oder schnellste) technische Lösung, während der Engineer mit der “Betriebsbrille” sicherstellen soll, dass eine Applikation einwandfrei funktioniert.

Legen wir den Fokus dabei auf Softwareentwickler und Betrieb finden wir eine Menge Informationen. In den Dokumentationen finden wir so z.b.. UML Flows für die Applikation, standardisierte Datenmodelle, Architektur Diagramme, Runbooks, TroubleShooting Guides,… usw. Jede Zielgruppe dokumentiert und beschreibt Ihre Sicht der Welt nach bestem Wissen und Gewissen (ich sage dabei nicht das Dokumentation schreiben je populär gewesen ist).

Was aber ist mit den Schnittmengen? Was ist mit den Informationen welche dem Entwickler und dem Betrieb gleichermaßen zur Verfügung stehen müssen?

Fragen wie:

  • Wie wird die Applikation installiert?
  • Wie wird die Applikation updated ?
  • Wie wird eine Entwicklungsumgebung installiert ?
  • Welche Version der Applikation ist auf welchem Environment installiert?
  • Welche Schritte sind notwendig um eine “frische Umgebung” mit der Applikation zu bespielen?
  • Welche Abhängigkeiten gibt es ? sind für beide Parteien interessant und relevant.

Aus der Vergangenheit heraus betrachtet neigen die Stakeholder allerdings dazu, die für sie relevanten Informationen für sich aufbereitet separat zu dokumentieren.

Der Effekt ist das Dokumentationen oft redundant geführt und in der Regel auch veraltet sind. Der Entwickler erfasst eine neue Version mit der entsprechenden Installationsanleitung (oder eine Kopie der vorangegangenen), der Betreiber erfasst nach erfolgreicher Installation die aktuelle Version der Umgebung “xyz”.

Dokumentation

Während klassische Entwickler in Zyklen arbeiten, arbeitet der Betrieb in Stabilisierung einer Applikation und Service Level Agreements.

Aufgrund der Unterschiedlichen Ausrichtung der Ziele werden so häufig unterschiedliche Tools genutzt um die jeweiligen Informationen bedarfsgerecht aufzubereiten.

Während ein Entwickler eine Sprintübersicht (SCRUM/KANBAN… etc.) bevorzugt, möchte sich ein Betreiber eine Übersicht über das jeweilige System verschaffen und dokumentiert gerne in Wiki, Confluence (bitte kein Excel/Word). Voneinander abweichende Dokumentationen des gleichen Systems verbessern die Qualität der Informationen in den seltensten Fällen.

Transparenz und Nachvollziehbarkeit

Ein heikles Thema.

Ein guter Betreiber schützt seine heilige Kuh, seine produktive Umgebung wie eine Glucke Ihr Junges. Klassiker wie:

  • Entwickler haben die Verantwortung und Hoheit über development und integrations Umgebungen
  • Betreiber haben die Verantwortung über die Produktion
  • Automatische Installationen dürfen nur bis zu einer gewissen “Stage” vorgenommen werden, um die Betriebsfähigkeit zu gewährleisten
  • Entwickler dürfen sich nicht mit einer produktiven Verbinden (tun es aber doch um auftretende Fehler zu beheben) finden sich auch heute noch in diversen Unternehmungen.

Konfigurationen und Quelltext sind voneinander getrennt, die Verantwortlichkeiten ebenfalls. Auch dieser Umstand verbessert die Fehleranfälligkeit und Stabilität einer Umgebung in den seltensten Fällen.

Ein paar “typische” Symptome:

  • vergessene/ungleiche Konfigurationen
  • abgelaufene Zertifikate
  • falsche Hostnamen
  • ein bekannter Fehler tritt mehrfach auf
  • Backup vergessen?
  • … Die o.a. Liste ließe sich beliebig erweitern.

Ein Lösungsansatz

Gemeinsame Dokumentation

Entwickler und Betreiber dokumentieren am gleichen Ort.

“…klingt simpel.
ist es aber nicht…”

Die Interessenkonflikte der einzelnen Parteien lösen sich nicht durch eine gemeinsame Sammlung von Informationen in Luft auf. Zumindest wird aber das redundante Erfassen von Informationen (“… auf welcher Confluence Page finde ich die aktuellen Informationen zu “xyz”…) schon einmal verbessert.

Transparente Dokumentation

Haben sich Entwickler und Betreiber auf eine gemeinsame Dokumentation geeinigt gilt es diese so transparent wie möglich zu gestalten.

“Ist lückenlos nachvollziehbar zu welcher Zeit jemand eine Information geändert hat ? “

Ist die Schlüsselfrage die sich immer mit der Antwort “JA” beantworten lassen sollte.

Dadurch ist auch im nachhinein für jeden ersichtlich warum jemand nachts um 1 die config “xyz” geändert hat und vor allem für welche Systeme. Für einen Frühdienst wesentlich angenehmer als eine Seitenlange Email mit Erklärungen. Diese Vorgehensweise hat eine weitere Dimension. Wenn die, auf den System befindlichen Informationen, immer transparent geändert werden, schafft das Vertrauen. Jeder weiss was ein anderer am System geändert hat und wozu. Das eliminiert Mißtrauen, es befindet sich ja alles transparent in einer gemeinsamen Dokumentation. Entwickler und Betreiber haben die exakt gleiche Informationsbasis (apropos, mir ist durchaus bewusst das es sich in einigen Fällen um dieselbe Person handelt).

Was hat das alles mit Dev Ops zu tun ?

Geteile Information ist geteiltes Leid

Wenn alle auf die exakt gleiche Datenbasis zugreifen und diese Transparent den Zustand der Software/Zielsysteme spiegelt, warum sollte man dann eine “Gewaltentrennung” der Verantwortlichkeiten weiterhin forcieren ? Warum können nicht verschiedene Teams gemeinsam für den Erfolg eines “Projektes”, oder einer gemeinsamen Plattform verantwortlich sein?

Die gemeinsame Zusammenarbeit aller Stakeholder, bei geteilter Verantwortung ist ein Kernelement der Dev/Ops Ideologie. Geteilte Verantwortung heißt allerdings Rechte UND Pflichten. Kollaboration ist der Schlüssel zum Erfolg, eine gemeinsamer (dokumentations) Datenbestand die solide Basis.

Für uns als Firma ist das oberste Ziel dabei: Transparenz

Warum nutzen wir GitOps ?

Nach den, etwas ausschweifenden, Erklärungen oberhalb dieser Zeilen, müssen wir eigentlich nur noch die letzten zwei logischen Schritte gehen:

1. Systemdokumentation im Git

Wir dokumentieren bei CAOS alle (und ich meine ALLE) Informationen, welche zu einer bestimmten Umgebung gehören in einem dedizierten “Ops” Repository. Unser Ziel dabei ist eine komplett neue Umgebung mithilfe unseres Repositories innerhalb weniger Minuten zu reproduzieren.

Und zwar immer identisch, immer auf die gleiche Weise.

Das heisst wir dokumentieren nicht nur das “Was”, sondern auch das “Wie”. Und zwar für alle Umgebungen und jedes Detail.

Killerargument diverser Security Officer an dieser Stelle: “… was macht ihr mit Secrets/Passwörtern und Benutzernamen” ?

Die Dokumentation beinhaltet den Speicherort der jeweiligen verschlüsselten Informationen. Die Zugangsbeschränkungen zu Systemen wie “gopass, hashicorp vault, sops, etc…” werden separat verwaltet. (und das sollten sie auch). Änderungen an Passwörtern behandeln wir auch wenn sie verschlüsselt sind identisch. (“… wer hat wann welches Passwort geändert und warum …”). Nur eben verschlüsselt.

2. Dokumentation als Zielzustand

Wenn nun alle Informationen Environment spezifisch vorhanden sind, warum nutzen wir sie nicht durch Automatismen ? Trennen wir mal zwei Arten von Informationen voneinander.

Den Soll und den Ist Zustand (ja, das ist ein alter Hut).

Was wäre wenn wir den Soll-Zustand einer Umgebung im Git beschreiben und ein Mechanismus diesen auf immer gleiche Art und Weise in einen Ist-Zustand überführt ? Der Ist-Zustand wird dann als “live” Dokumentation ins Git geschrieben.

In der Kubernetes Welt machen das Operator, Reconciler, Automaten… etc.

Ich habe bewusst auf zu viel TechTalk verzichtet um die Idee “GitOps” ins Zentrum zu bringen, ohne eine gewisse Grundhaltung funktioniert das Konzept nur bedingt bzw. nicht.

Beispiel:

  • Zum Upgrade einer Applikation müsste nun also im Ops Repository in der (Soll) Applikationsbeschreibung die Version der Applikation von 1 auf z.b. 1.1 geändert werden. (dies kann durch eine Person, eine build pipeline, etc. geschehen)
  • Auf dem Zielsystem befindet sich eine Komponente, die den Inhalt des Repositories periodisch überprüft. (Abgleich Soll/Ist).
  • Die Komponente stellt fest, dass sich die Version geändert hat und updated das System gemäß ihrer Beschreibung/Anweisung
  • Nach Abschluss wird der Ist Zustand ins Git quittiert.
  • Die Dokumentation des Ist Zustands aktualisiert sich also “quasi” von selbst bzw. durch einen immer identisch handelnden Prozess

Sowohl Integrationstests, Smoketests, Backups, Datentransformationen, Testdatenanonymisierung, Passwort Änderung; jede erdenkliche Notwendigkeit der “Ops” Tätigkeit lässt sich sinnvoll automatisieren. Der Vorteil liegt auf der Hand:

  • Wenn die Aktionen immer auf die gleiche Art und Weise durchgeführt werden und alle Anweisungen und Informationen transparent im Git dokumentiert sind:
  • Bekommen wir identische und reproduzierbare Ergebnisse. —> JEDES MAL
  • Sind alle Änderungen transparent im Git dokumentiert und zwar in Echtzeit
  • Kommen wir von einem Push Ansatz zu einem Pull Ansatz. Das Zielsystem “zieht” sich die Informationen (oder mehrere Zielsysteme)
  • Können sich Entwickler und Betrieb um sinnvollere Aufgaben kümmern als das copy/pasten von Installationsanleitungen und der nachfolgenden Kontrolle und Dokumentation
  • Haben alle Teilnehmer den gleichen Stand über den Zustand eines oder mehrerer Systeme
  • Können im Falle eines Fehlers/Ausfalls Rollbacks im Git gemacht werden oder eine komplett neue Umgebung identisch beschrieben installiert werden

GitOps @ CAOS

Mit dem Pattern GitOps kamen wir erstmals durch die Firma Weaveworks in Berührung, Siehe: a guide to git ops. Abseits der technischen Umsetzung ging mit der Einführung des Patterns ein Umdenken einher.

Zum Einen “deployen” wir nicht mehr, sondern weisen Zielsysteme an, sich einen Zielzustand in definierten Zyklen zu “ziehen”. So charmant dieses System auch ist, es setzt Git als “single point of truth” voraus. Eine lokale Änderung wird nämlich beim nächsten Abgleich “Soll/Ist” sofort wieder überschrieben. Auch müssen die Automaten, welche den Zielzustand herstellen, immer einwandfrei funktionieren (und sich nicht zu einem technischen Monster entwickeln das unbeherrschbar wird). Je nach Applikation bedeutet das initialen Aufwand, der sich allerdings im Nachhinein ausbezahlt. Zu guter Letzt sollte Git immer verfügbar sein. Das sollte in der Softwarewelt Normalzustand sein, bekommt hier aber zusätzliches Gewicht.

Das heisst im Umkehrschluss, dass alle Projektteilnehmer die GitOps Logik auch benutzen und verstehen müssen. Nicht alle Projektteilnehmer sind Git-affin, andere bevorzugen ihr jahrelang abgehangenes Dokumentationssystem. Ein commit im Git löst unter Umständen eine direkte Änderung auf einem System aus, das fühlt sich für manche anfänglich “neu” an. Nach mehreren Jahren Erfahrung ist es für uns zur Normalität geworden. Es existiert keine dedizierte Person, die ein Software deployment vornimmt. Niemand der auf System “xyz” eine Konfiguration ändert. Wir sind ein Team, das gemeinsam mit Hilfe eines Git Repository kollaboriert. So lassen sich nun auch “reviews” durch git merge/pull requests nicht nur für Codeänderungen sondern auch für Konfigurationen oder Deployments nutzen, gerade in einer produktiven Umgebungen wird so das vier Augen Prinzip gewahrt.

Da wir unsere eigene Applikationen auf der Open Source Platform Kubernetes betreiben, bekommt das Pattern noch einen weiteren “boost”. Die Art und Weise wie in Kubernetes Applikationen deklariert werden begünstigt GitOps geradezu. Mehrfach täglich werden unsere Systeme deployed, gebackuped und getestet. Selbstverständlich ohne downtime.

Um dabei noch einen Schritt weiter zu gehen deklarieren wir mittlerweile auch unsere kompletten Kubernetes Cluster via GitOps durch unser OpenSource Projekt ORBOS. D.h. wir sind technisch in der Lage in wenigen Minuten von “Hardware/Virtuelle Maschine” zum HA Setup unseres Open Source IAM ZITADEL zu kommen. Unabhängig vom Provider oder Rechenzentrum, cloud oder on premise. Ich kann nun mit guten Recht behaupten das wir da auch ein kleines bisschen stolz drauf sind.

Hast Du Fragen oder Anregungen?

Twitter

[email protected]

Christian Jakob

Cover art by Glenn Carstens-Peters on Unsplash