Continuous Delivery (CD) hat sich im Umfeld agiler Softwareentwicklung und als ein Kernelement von DevOps als adäquates Vorgehen erwiesen, qualitativ hochwertige Software in kurzen Zyklen zuverlässig und wiederholbar zu veröffentlichen. Der State of Continuous Delivery Report 2022 hat ergeben, dass DevOps und Continuous Delivery in durchschnittlich ca. 80 Prozent aller Branchen und Unternehmensgrößen eingesetzt werden. Die Bereiche Web Apps und Software as a Service liegen mit 81 Prozent im Mittelfeld.

Dieser Report zeigt auch, dass Release-Zyklen in der Regel durch den Einsatz von Containern und Kubernetes deutlich kürzer sind. Auch Wiederherstellungszeiten sind deutlich kürzer und die Häufigkeit von Deployments ist höher. Die Kombination von Continuous Delivery in Verbindung mit Containern und Kubernetes (K8s) ist also sehr vielversprechend für gute Entwicklungsgeschwindigkeit.

Klassische CD-Pipelines nutzen einen Continuous-Integration-(CI)-Server, mit dem Container zum Test ausgeführt und anschließend in ein Container-Image verpackt und auf verschiedenen Betriebsumgebungen deployt werden. Dieses klassische Vorgehen, auch CIOps genannt, ist mittlerweile sehr etabliert, weswegen viele der Nachteile oft einfach akzeptiert oder Workarounds genutzt werden.

Im Kubernetes-Umfeld gibt es mit GitOps mittlerweile eine Alternative, die besonders im Hinblick auf Reproduzierbarkeit, Auditierbarkeit und Sicherheit Vorteile bietet.

CIOps vs. GitOps – in aller Kürze

Beim klassischen CIOps führt ein CI-Server aktiv das Deployment in die Betriebsumgebung durch (siehe Abbildung 1).

Abbildung 1: CIOps-Prozess

CIOps-Prozess

Der Nachteil dieses Vorgehens ist, dass für jedes Deployment ein Build im CI-Server durchlaufen werden muss. Das macht den Prozess langsamer. Denn generell soll ja dasselbe Artefakt auf allen Stages deployt werden. Es wäre also gar kein neuer Build, Test oder gar Versionsname nötig. Außerdem muss der CI-Server schreibenden Zugriff auf die Betriebsumgebung haben. Dies ist in Anbetracht aktueller, erfolgreiche Angriffe auf die Supply-Chain (beispielsweise gegen die Firmen Okta oder SolarWinds) nicht ideal.

Doch was ist GitOps? Kurz gesagt ist GitOps eine Methode, bei der eine im K8s-Cluster laufende, Cloud-native Anwendung (der „GitOps-Operator“) kontinuierlich den tatsächlichen Zustand des Clusters gegen den Wunschzustand, der in einem Git-Repository beschrieben ist, abgleicht. Deployments werden durch einen Push auf dieses Repository, beispielsweise durch die Annahme eines Pull Request, ausgelöst (siehe Abbildung 2). Der Vergleich zwischen Ist- und Soll-Zustand wird durch deklarative Beschreibung des Soll-Zustands mittels Infrastructure as Code (IaC) ermöglicht.

Abbildung 2: GitOps-Prozess

GitOps-Prozess

Dadurch ergeben sich durch GitOps diese Vorteile:

  • Weniger schreibender Zugriff von außen auf den Cluster nötig, da der GitOps-Operator Deployments von innerhalb des Clusters durchführt.
  • Keine Credentials im CI-Server, da kein Zugriff auf den Cluster benötigt wird und das imperative Einfügen von Anwendungs-Credentials nicht mehr möglich ist (stattdessen Verwendung von Secrets Management).
  • Vollständig in Git versionierter Infrastructure as Code (IaC) bietet Vorteile für Auditierung und Reproduzierbarkeit. Außerdem sind Cluster und Git automatisch synchronisiert.
  • Der Zugriff auf Git ist oft organisatorisch einfacher als der auf den API-Server. Möglicherweise entfällt die Notwendigkeit einer Firewall-Freischaltung.
  • Einfachere Disaster Recovery, da die gesamte Infrastruktur im Git liegt und damit quasi das Backup zumindest für stateless Workloads entfällt.

Große Auswahl an günstigen Domain-Endungen – schon ab 0,08 € /Monat
Jetzt Domain-Check starten

CI-Server und GitOps

Für das Deployment von Third-Party-Anwendungen (die nicht selbst entwickelt werden) ist mit GitOps kein CI-Server mehr unbedingt nötig. Bei selbst geschriebenen Anwendungen sind nach wie vor Build, Tests, etc. auszuführen. Dies übernimmt weiterhin der CI-Server, genauso wie das Pushen des Images in eine Registry (siehe Abbildung 3).

Abbildung 3: GitOps-Deployment von selbst entwickelten Images

GitOps-Deployment von selbst entwickelten Images

Außerdem kann der CI-Server eingesetzt werden, um einige der Herausforderungen von GitOps zu lösen:

  • Die manuelle Implementierung von Staging kann umständlich sein (für jede Stage muss ein PR erstellt werden).
  • Oft wird bei GitOps der Infrastruktur-Code in einem zentralen Repository gesammelt. Dies bietet den Vorteil, dass der gesamte Zustand des Clusters an einer Stelle gespeichert ist. Der Nachteil: Die Trennung von Anwendungs- und Infrastruktur-Code auf zwei Repositories ist aufwändiger zu warten, beispielsweise bei Review, Versionierung und lokaler Entwicklung. Hier kann der CI-Server abhelfen, indem er den im Anwendungs-Repository gepflegten Infrastruktur-Code in das GitOps-Repository pusht.

Vorteile von GitOps

Erhöhte Produktivität

Durch die Automatisierung von Deployment-Prozessen, sowohl in der Entwicklung als auch im Betrieb von Anwendungen, wird die Produktivität der Organisation erhöht. GitOps ist dabei besonders effektiv und vereint die Vorteile einer Vielzahl an Tools:

  • Schnelle Veröffentlichung von Änderungen: Durch die Nutzung von Kubernetes ist es möglich, Deployments von Anwendungen durchzuführen, ohne dass deren Verfügbarkeit unterbrochen wird (No Downtime Deployments). Im Zusammenspiel mit der Reconciliation Loop können so Code-Änderungen unverzüglich und mit minimalem manuellem Aufwand veröffentlicht werden.
  • Reproduzierbarkeit der Infrastruktur: In GitOps wird die Infrastruktur nach dem Prinzip der Infrastructure as Code (IaC) deklariert. So bietet GitOps eine bessere Skalierbarkeit der Infrastruktur bei gleichzeitig sinkendem Verwaltungsaufwand. Dadurch wird der Betrieb kosteneffizienter als mit klassischen Prozessen.
  • Schnellere Wiederherstellung nach Ausfall (Rollbacks): Durch die Versionierung aller Änderungen, sowohl Code der Anwendung an sich als auch der Infrastruktur für den Betrieb in Git, ist es ein Leichtes, den Stand eines beliebigen Commits wiederherzustellen. Dadurch werden die Ausfallzeit und der Aufwand zur Wiederherstellung reduziert.
  • Vereinfachte Berechtigungsstrukturen: Mit GitOps werden Änderungen durch den GitOps-Operator nach dem Pull-Prinzip in den Cluster hineingezogen und nicht durch den CI-Server nach dem Push-Prinzip auf den Server geschoben. Dadurch entfallen für viele Unternehmen zeitaufwändige Freischaltungen, wenn zum Beispiel CI-Server und Deployment-Ziel durch eine Firewall getrennt sind oder sich in unterschiedlichen Zonen befinden. Durch die Kombination der Eigenschaften von Kubernetes, IaC und Git können Teams häufiger und schneller Änderungen ausliefern und dadurch ihre Produktivität erhöhen.

Erhöhte Sicherheit

In klassischen CI/CD-Pipelines ist der Build Server eine zentrale Komponente, die sowohl den Code kompiliert, als auch Deployments vornimmt. Das macht ihn zu einem begehrten Angriffsziel von Cyber-Kriminellen.

Im Gegensatz dazu wird der Build-Server in GitOps ausschließlich zum Bauen von Artefakten benutzt und benötigt keinen Zugriff auf den Cluster. Im Build-Server müssen keine Zugangsdaten für das Deployment von Anwendungen hinterlegt werden. Darüber hinaus wird die Kontrolle über Deployments in den Cluster gegeben, weil GitOps ermöglicht, die Deployments nach dem Pull-Prinzip und nicht mehr nach dem Push-Prinzip durchzuführen. Informationen werden dadurch in den Cluster verlagert und weniger schreibender Zugriff von außen auf den Cluster benötigt.

Auch Zugangsdaten und Secrets für Anwendungen und Datenbanken, etc. sollten nicht im Klartext im Git gespeichert werden, da solch sensible Informationen erfahrungsgemäß ein großer Angriffsvektor sind. GitOps unterstützt eine Vielzahl von Operatoren, welche für die Ver- und Entschlüsselung benutzt werden können. Da GitOps in vielen Fällen Änderungen am Umgang mit Secrets voraussetzt, werden Sie später in diesem Artikel noch mehr zu den GitOps-Herausforderungen im Bezug auf den Umgang mit Secrets erfahren.

Verbesserte Nachvollziehbarkeit und Auditierbarkeit

In fast allen Industriezweigen gibt es rechtliche Anforderungen, um elektronische Aufzeichnungen über wichtige Elemente zu speichern, die für die Verhinderung von Sicherheitslücken, Einhaltung von Compliance und mehr genutzt werden. Es ist also notwendig zu dokumentieren, wann und von wem Änderungen durchgeführt wurden, um im Schadensfall den Ursprung exakt nachvollziehen zu können.

Durch die vollständig deklarative Beschreibung in GitOps werden alle Änderungen an der Infrastruktur (IaC) durch die Versionskontrolle in Git gespeichert. In dieser wird genau festgehalten, wann und von wem eine Änderung gemacht wurde und wer vielleicht noch ein Review durchgeführt hat. Die Commit Messages können genutzt werden, um den Grund für Änderungen festzuhalten. Beispielsweise kann durch die Angabe einer Ticket-Nummer direkt der Bezug zur Fachlichkeit hergestellt werden. Zusätzlich sind keine imperativen Schritte durch den CI-Server notwendig, wodurch auch hier keine undokumentierten Schritte erfolgen. Durch diese Eigenschaften verbessert GitOps die Auditierbarkeit bereits ohne weitere Maßnahmen.

Erhöhte Zuverlässigkeit

Zusätzlich zur verbesserten Robustheit der Prozesse durch die deklarative Beschreibung und die umfängliche Automatisierung wird die Zuverlässigkeit durch GitOps mit Hilfe der Operatoren verbessert. In diesen läuft die Reconciliation Loop, die den im Git-Repository beschriebenen Soll-Zustand fortlaufend mit dem Ist-Zustand des Clusters synchronisiert. Abweichungen, beispielsweise durch menschliche Fehler oder Angreifer, werden dadurch automatisch erkannt und behoben.

Außerdem wird die Zuverlässigkeit durch die bereits beschriebene Verkürzung von Wiederherstellungszeiten und die Single Source of Truth verbessert. Dadurch werden Ausfallzeiten verkürzt und versehentliche Änderungen minimiert.

Herausforderungen von GitOps

Wie bereits erwähnt, erfordert der deklarative Ansatz von GitOps, dass bestehende Prozesse nicht wie bisher weiterverwendet werden können. Dadurch entstehen natürlich Herausforderungen, für die es jedoch auch in den meisten Fällen schon Lösungen gibt.

Integration in bestehende Prozesse

Da sich der GitOps-Ansatz deutlich vom klassischen CIOps-Ansatz unterscheidet, ändern sich damit auch die entsprechenden Prozesse und Workflows. Ideal ist hierbei eine Lösung, welche die Änderungen für Betrieb und Entwicklung möglichst gering hält. In der Regel existieren bereits Pipelines, um Applikationen zu bauen und zu releasen. Das Ziel sollte sein, die bestehenden Pipelines so anzupassen, dass eine Ausbringung per GitOps ohne größeren Aufwand realisiert wird. Ein Einstieg auf einer grünen Wiese ist aber wegen der recht steilen Lernkurve ideal.

Stages und Struktur der Repositories

Durch den Einsatz von GitOps wird der gesamte Cluster-Zustand über Git-Repositories abgebildet, was zu einer erhöhten Anzahl an Repositories, Branches und Ordnern führt. Es ist deshalb empfehlenswert, sich bereits im Vorfeld zu überlegen, wie diese organisiert werden können. Damit stellen Sie sicher, dass Ihre GitOps-Prozesse übersichtlich und wartungsfreundlich werden. Zusätzlich stellt sich die Frage, wie die Staging-Strategie aussehen soll. Eine Möglichkeit ist es, Staging-Namespaces im gleichen Cluster zu benutzen. Dafür wird nur ein GitOps-Operator benutzt, um alle im GitOps-Repository befindlichen K8s-Ressourcen in den Cluster zu deployen. Dabei muss lediglich auf die Angabe des richtigen Namespaces in den K8s-Ressourcen geachtet werden.

Alternativ können auch Staging-Cluster benutzt werden, in denen der jeweilige GitOps-Operator so konfiguriert wird, dass er alles deployt, was im jeweiligen Ordner seiner Stage liegt. Der GitOps-Operator des Staging-Clusters deployt nur K8s-Ressourcen aus dem Ordner “staging”.

Abbildung 4: Beispiel einer Ordnerstruktur für Staging mit GitOps

Beispiel einer Ordnerstruktur für Staging mit GitOps

Secrets

Durch IaC und den deklarativen Ansatz von GitOps wird eine geänderte Handhabung von Secrets erzwungen, da durch das Speichern des gesamten Zustands in Git unweigerlich ein Weg gefunden werden muss, auch Secrets dort einzubringen. Direkt und unverschlüsselt im Git gespeichert, bieten diese dort jedoch eine große Angriffsfläche. Deswegen gibt es grundsätzlich zwei Ansätze:

  • Verschlüsselte Speicherung der Secrets in Git
  • Speicherung der Secrets in einem Key Management Systems (KMS) und Referenzierung in Git.

Für beide Ansätze gibt es Operatoren, die benutzt werden können. Der am weitesten verbreitete Operator zur verschlüsselten Speicherung von Secrets in Git ist Sealed Secrets von Bitnami. Für die Nutzung eines KMS gibt es unterschiedliche Möglichkeiten:

  1. Betreiben eines speziellen Operators (z.B. mit External Secrets)
  2. Mounten von Secrets in das File-System mittels Container Storage Interface (CSI) (mittels CSI Driver)
  3. Einfügen (injecten) eines Side cars in Pods (z.B. mit Hashicorp Vault k8s)
  4. GitOps-Operator mit entweder nativen Support für KMS oder via Plugin (z.B. mit sops-secrets)

Unabhängig davon, ob Sie den Einsatz von GitOps in Betracht ziehen oder nicht, sollten Sie, wenn noch nicht der Fall, Ihren Umgang mit Secrets evaluieren. Die hier vorgestellten Methoden können auch ohne GitOps angewendet werden und verbessern die Sicherheit Ihrer Infrastruktur.

Asynchronität und Fehlerbehandlung

In klassischen Pipelines, in denen Kubernetes-Kommandos direkt ausgeführt wurden, können auftretende Fehler direkt verarbeitet und gemeldet werden. Durch den asynchronen Charakter, den GitOps mit sich bringt, wird auch die Fehlerbehandlung unweigerlich schwieriger. Da Fehler erst dann auftreten, wenn die Ressourcen vom GitOps-Operator tatsächlich angewandt wurden, müssen diese Fehler in einer asynchronen Art behandelt werden. Dazu bringen die GitOps-Operatoren häufig Tools für Benachrichtigungen oder Metriken mit. Zusätzlich lassen sich auch Validierungsmechanismen mittels CI-Pipelines implementieren, mit denen Feedback-Zyklen verringert werden können („Fail early“). In erster Linie betrifft dies Syntaxfehler.

Darüber hinaus ist diese Art der Validierung im Zusammenspiel mit Cluster Policies sinnvoll. Ressourcen, die eine oder mehrere Policies verletzen, werden vom Admission Controller abgelehnt und werden nicht auf den Cluster angewandt. Durch die Asynchronität kriegt man das aber nicht direkt mit, was die Fehlerbehandlung erschweren kann. Durch ein Testen der Ressourcen gegen die Policy Definitionen mittels entsprechender Tools in einer CI-Pipeline können mögliche Fehler vor dem Ausbringen durch den GitOps-Operator korrigiert werden.

GitOps Tools

Die momentan bekanntesten GitOps Tools sind ArgoCD und Flux v2. Beide Tools bieten viele identische Funktionen, haben aber auch ihre Unterschiede.

Folgende Fähigkeiten bringen sowohl Flux v2 als auch ArgoCD mit:

  • RBAC
  • Multi-Tenancy
  • Observability (Health Status, Notifications, Metriken)
  • CLI für Automatisierung und CI-Integration
  • Start der Synchronisation per Webhook
  • Aufruf von Webhooks bei Events (ArgoCD: Hooks, Flux: Notifications)
  • Rollback/Roll-anywhere zu bestimmten Commits im Git-Repository
  • Unterstützung für Helm und Kustomize
  • Multi-Cluster-Unterstützung
  • Ausführung der Container als unprivilegierter User
  • Security Context konfigurierbar
  • automatisches Update der Image-Version im Git-Repository

Funktionen nur in ArgoCD:

  • Unterstützung für Ksonnet und Jsonnet und weitere per Plug-in-Mechanismus
  • Weboberfläche zur Administration und Überwachung von Applikationen in Echtzeit
  • SSO-Integrationen für UI und CLI
  • Preview Environments (via ApplcationSets)
  • Weiterer Operator, um mehrere ArgoCD-Instanzen mittels deklarativer Beschreibung zu betreiben

Funktionen nur in Flux v2:

  • Definition von Abhängigkeiten in Helm- und Kustomize-Applikationen
  • Unterstützung von SOPS
  • Authentifizierung des CLI per Kubeconfig
  • Visual Studio Code Plugin
  • Support for OCI anstelle von Git
  • Terraform Operator

Einen ausführlichen Vergleich der beiden Tools finden Sie in dem Artikel “Automatisierungsgehilfen: GitOps-Tools im Vergleich” und in diesem aktuellen Forumsbeitrag.

GitOps ausprobieren – GitOps Playground

Durch seinen deklarativen Ansatz bedeutet GitOps einen fundamentalen Wechsel darin, wie Infrastruktur gedacht wird. Wenn Sie das Konzept interessant finden, können Sie GitOps ohne viel Aufwand ausprobieren und in Aktion sehen – mit dem GitOps Playground. Dieser steht als Open Source Projekt bereit und ermöglicht es, mit einem einzigen Befehl einen leichtgewichtigen K8s-Cluster zu starten und mit allen Tools, die man für GitOps braucht, zu initialisieren. Anhand von Beispiel-Anwendungen kann man Flux und ArgoCD ausprobieren, und auch das Zusammenspiel mit Secrets Management und Monitoring/Alerting ist integriert.

Abbildung 5: GitOps-Playground Infrastruktur

GitOps-Playground Infrastruktur

Für wen ist GitOps sinnvoll?

GitOps bietet zahlreiche Vorteile, die sowohl Zeit als auch Kosten einsparen und gleichzeitig die Sicherheit der Infrastruktur und Auditierbarkeit verbessern. Deswegen könnte die Schlussfolgerung sein, dass GitOps das Nonplusultra ist und alle anderen Ansätze der Vergangenheit angehören. Das wäre jedoch eine sehr eindimensionale Betrachtung. Fakt ist nämlich auch, dass die Einführung von GitOps die in diesem Artikel beschriebenen Herausforderungen mit sich bringt. Wenn in einem Unternehmen schon ein gut funktionierendes CIOps etabliert ist und es keine Probleme gibt, für die die Vorteile von GitOps eine Lösung sein könnten, dann lohnt sich ein Umstieg wahrscheinlich wegen des hohen initialen Aufwands nicht. Wenn jedoch ein Projekt auf der grünen Wiese startet und schon Vorwissen im Umgang mit Kubernetes vorhanden ist, dann kann GitOps sehr wohl eine gute Wahl sein, um eine hohe Produktivität, Sicherheit und Nachvollziehbarkeit zu erreichen.

Titelmotiv: Bild von Wynn Pointaux auf Pixabay

Daniel Huchthausen

Große Auswahl an günstigen Domain-Endungen – schon ab 0,08 € /Monat
Jetzt Domain-Check starten