Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
GitOps optimal einsetzen - Praktischer Einstieg für Entwicklungs- und Plattformteams - tiefgründige Fokussierung auf GitOps (ohne Grundlagen für K8s oder CI/CD) - Klarer Einblick in die Konsequenzen von GitOps und den Unterschied im Entwicklungsalltag - Umfassende Hilfestellung zu relevanten Herausforderungen wie Secrets, Repo-Strukturen und Asynchronität GitOps ist die aktuell vielversprechendste Methodik, um Continuous Deployment auf Cloud-native Art und Weise umzusetzen. Im Gegensatz zu punktuell getriggerten Deployments werden deklarative Beschreibungen der Softwaresysteme genutzt, um diese kontinuierlich im Hintergrund anzuwenden. Mit diesem Buch kannst du schnell und einfach in GitOps einsteigen und erfährst seine Vorteile für den Entwicklungsalltag. Nicht nur vergleichen wir hierfür die Tools Argo CD und Flux, sondern zeigen auch konkrete Implementierungen von GitOps mit und ohne Kubernetes, die du anhand öffentlicher Repositories direkt nachstellen kannst. Überdies gehen wir ausführlich auf fortgeschrittene Themen wie Secrets Management, Repo-Strukturen, Asynchronität und Alerting ein, um dich für den Ein- bzw. Umstieg optimal vorzubereiten. Unter https://gitops-book.dev findest du weitere Informationen zum Thema.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 432
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Baris Cubukcuoglu ist Cloud Solution Engineer bei Mimacom und verfügt über mehr als 10 Jahre Erfahrung in der Entwicklung und Architektur von Anwendungen. Seine Passion ist es, Dinge umzusetzen, die einen Mehrwert schaffen. Dabei berät und unterstützt er Kunden bei Cloud- und Infrastruktur-Technologien, Kubernetes sowie bei der automatisierten Auslieferung von Software mit CI/CD.
Josia Scheytt befähigt Entwicklungsteams dazu, zügig und mit Zuversicht nach Produktion zu deployen. Mit Fokus auf Public Cloud, Kubernetes und CI hilft er verschiedenen Kunden in seiner Tätigkeit als Cloud Automation Engineer bei Mimacom (www.mimacom.com).
Johannes Schnatterer war bereits jahrelang in der Softwareentwicklung tätig bevor sein Fokus mit dem Aufkommen der Containertechnologie in Richtung Infra-Themen zu wandern begann. Als Technical Lead der Infra- und Consulting Teams bei Cloudogu entwickelt und betreibt er eine Internal Developer Platform auf Basis von Kubernetes und GitOps und gibt dabei Gelerntes als Consultant, Trainer und Autor weiter.
Copyright und Urheberrechte:
Die durch die dpunkt.verlag GmbH vertriebenen digitalen Inhalte sind urheberrechtlich geschützt. Der Nutzer verpflichtet sich, die Urheberrechte anzuerkennen und einzuhalten. Es werden keine Urheber-, Nutzungs- und sonstigen Schutzrechte an den Inhalten auf den Nutzer übertragen. Der Nutzer ist nur berechtigt, den abgerufenen Inhalt zu eigenen Zwecken zu nutzen. Er ist nicht berechtigt, den Inhalt im Internet, in Intranets, in Extranets oder sonst wie Dritten zur Verwertung zur Verfügung zu stellen. Eine öffentliche Wiedergabe oder sonstige Weiterveröffentlichung und eine gewerbliche Vervielfältigung der Inhalte wird ausdrücklich ausgeschlossen. Der Nutzer darf Urheberrechtsvermerke, Markenzeichen und andere Rechtsvorbehalte im abgerufenen Inhalt nicht entfernen.
Baris Cubukcuoglu · Josia Scheytt · Johannes Schnatterer
Grundlagen und Best Practices
Baris Cubukcuoglu
Josia Scheytt
Johannes Schnatterer
Lektorat: Dr. Benjamin Ziech
Lektoratsassistenz: Julia Griebel
Copy-Editing: Annette Schwarz, Ditzingen
Satz: Da-TeX Gerd Blumenstein, Leipzig, www.da-tex.de
Herstellung: Stefanie Weidner, Frank Heidt
Umschlaggestaltung: Eva Hepper, Silke Braun
Bibliografische Information der Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
ISBN:
978-3-86490-996-2
978-3-98890-012-8
ePub
978-3-98890-123-1
1. Auflage 2024
Copyright © 2024 dpunkt.verlag GmbH
Wieblinger Weg 17
69123 Heidelberg
Schreiben Sie uns:
Falls Sie Anregungen, Wünsche und Kommentare haben, lassen Sie es uns wissen: [email protected].
Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.
Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.
Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autoren noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.
Wir Autoren haben in Summe mehrere Jahrzehnte Erfahrung in den unterschiedlichsten Softwareprojekten gesammelt, teilweise als Softwareentwickler, oftmals als Platform Engineers. Uns sind Firmen und Problemstellungen mit unterschiedlichsten Größenordnungen, Branchen, Organisationsstrukturen und Deploymentwegen begegnet, und in alldem hat sich wenig so universal bewährt wie GitOps.
GitOps ist kein Tool, auch wenn es ohne gute Tools schwer umzusetzen ist. Statt eines Tools begegnen uns in GitOps eine Methodik, ein Satz an Grundprinzipien und eine Sammlung an etablierten Praktiken, mit deren Hilfe wir punktuell ausgeführte Deployments aus guten Gründen hinter uns lassen können. Und weil der Umstieg auf diese Methodik weit mehr als das Installieren eines Operators bedeutet, widmen wir diesem Thema ein umfassendes Buch.
Unsere Vision ist es, Entwicklungsteams im ganzen deutschsprachigen Raum zu helfen, in GitOps hineinzuwachsen. Wir wünschen uns, dass gerade kleine Teams ohne dedizierte DevOps-Kapazitäten in den Genuss derjenigen Vorteile von GitOps kommen, die wir mit traditionellem CIOps bisher nicht erreichen konnten:
weitreichendere Automatisierung von Deployments
höhere Stabilität unserer Softwaresysteme
geringere Komplexität im Betrieb
eine in Summe bessere Developer Experience
erleichterter Zugang zu Kubernetes und dadurch leichteres Erlernen der Plattform
Wir erwarten, dass GitOps in wenigen Jahren der etablierte Standardweg sein wird, Kubernetes als Anwendungsentwickelnde zu nutzen. Unsere Hoffnung ist es, mit diesem Buch einen Beitrag zur Verbreitung von GitOps zu leisten.
GitOps ist aus den Erfahrungen von DevOps, Continuous Integration (CI), Continuous Deployment (CD) und Infrastructure as Code (IaC) hervorgegangen. Außerdem finden wir momentan nur im Bereich von Kubernetes wirklich gutes Tooling, um GitOps umzusetzen.
Deswegen ist es für das Verständnis dieses Buches sehr hilfreich, wenn du oder ihr als Team folgende Vorkenntnisse mitbringt:
Ihr habt Erfahrung mit der Nutzung von CI/CD-Pipelines. (Die konkrete Plattform dafür spielt keine Rolle, und das Schreiben von Pipelines muss nicht eure Expertise sein, aber ihr solltet solche Pipelines aktuell nutzen.)
Ihr habt ein grundlegendes Verständnis von Kubernetes und wie man darauf Container deployt. (Kenntnisse im Administrieren eines Clusters sind nicht notwendig, aber ihr solltet aus der Sicht eines Kubernetes-Nutzers wissen, was ein Deployment ist.)
Unser Buch lässt sich grundsätzlich gut in der vorgegebenen Reihenfolge lesen. In Teil I beschäftigen wir uns mit den grundlegenden Fragen: Was ist GitOps, welchen Unterschied macht es im Entwicklungsalltag und wie fange ich praktisch mit GitOps an?
Teil II dreht sich dann um die Themen, die uns in der Praxis unmittelbar begegnen. Dabei gibt es einige Themen wie Secrets Management, Repo-Strukturen, Asynchronität und Alerting, bei denen ein allgemeines Verständnis zuerst wichtiger ist als ganz konkrete technische Implementierungen. Dennoch ist eine der sehr grundlegenden Entscheidungen, die wir beim Umstieg auf GitOps direkt am Anfang treffen müssen, die Wahl des GitOps-Operators. Mit Argo CD und Flux gibt es hier bereits zwei stark etablierte Tools.
Kapitel 4 streift bereits einige nachfolgende Themen von Teil II.
Weil die Wahl des Operators weitreichende Konsequenzen haben wird, stellen wir den Vergleich von Argo CD und Flux mit Kapitel 4 an den Anfang von Teil II. Wir streifen dabei auch einige der späteren Themen von Teil II. Wenn die Details von Kapitel 4 für den Anfang zu viel sind, dann kann es durchaus Sinn ergeben, dieses Kapitel anfangs zu überspringen und sich erst beispielsweise nach Kapitel 9 mit diesem Kapitel intensiver zu beschäftigen.
Teil III befasst sich mit weiterführenden Themen, die nicht immer unmittelbar mit dem Entwicklungsalltag zu tun haben, darunter die Verwaltung von Infrastruktur mittels GitOps und wie GitOps außerhalb von Kubernetes eingesetzt werden kann.
Softwareentwickelnde
Wir schreiben dieses Buch in der Hoffnung, dass Softwareentwickelnde in Stream-Aligned Teams, wie sie in »Team Topologies«1 beschrieben werden, zu schnelleren und stabileren Deployments befähigt werden. Damit sind Entwicklungsteams unsere primäre Zielgruppe.
Die Anforderungen, die heutzutage an Softwareentwicklung gestellt werden, reichen weit über reine Feature-Entwicklung hinaus und berühren auch Security und Finanzen. Mit »Shifting Left« sollen crossfunktionale Entwicklungsteams neben Feature-Entwicklung vermehrt auch viele dieser zusätzlichen Verantwortungen übernehmen.
Platform Engineers
Diese Komplexität ist oftmals zu viel für Entwicklungsteams, und deshalb bilden sich in vielen Organisationen sogenannte Plattformteams, die zentralisierte Services betreiben, um Entwicklungsteams mit geebneten Wegen viel kognitive Last abzunehmen. Unsere sekundäre Zielgruppe sind genau solche Platform Engineers.
Eine Kernkompetenz von Platform Engineering ist das Befähigen von Entwickelnden. In diesem Sinne sprechen wir zwar mit Teil III des Buches deutlich mehr Platform Engineers an, während Teil I und II aus Sicht von Platform Engineers besonders für das Enablement von Entwickelnden hilfreich sind, weil dort komplizierte GitOps-Konzepte gut zugänglich gemacht werden.
Wir nutzen im Buch folgende Hervorhebungen:
Kursiven Text
nutzen wir bei der ersten Erwähnung eines wichtigen Konzepts und auch zur generellen Hervorhebung im Fließtext.
Monospace
nutzen wir für Folgendes:
CLI-Befehle im Fließtext (zum Beispiel
kubectl apply
)
Namen von Custom Resource Definitions in Kubernetes (zum Beispiel
Kustomization
)
Dateipfade (zum Beispiel
ch05/bootstrap/argo-cd.yaml
)
Namen von Entitäten aus Code-Listings (zum Beispiel
podinfo
)
Abgesehen davon gibt es einige Blockformatierungen, die wir folgendermaßen nutzen:
Eine Nebenbemerkung, die oftmals externe Verweise enthält, zum Beispiel auf Beispiel-Repositories.
Exkurs
Eine Ausführung, die weiterführende Infos zum Thema gibt, aber zum Verständnis des Fließtexts nicht zwingend notwendig ist.
Wir wünschen viel Spaß beim Lesen unseres Buches und viel Gewinn davon für dein Team! Auf der Website zum Buch2 werden wir Neuigkeiten und (sofern nötig) Errata veröffentlichen.
Wir freuen uns sehr, wenn du uns Feedback zum Buch geben möchtest! Nutz dafür gerne die Website zum Buch oder kontaktiere uns auf LinkedIn.
Vorwort
Teil IGrundlagen
1Was ist GitOps?
1.1CIOps vs. GitOps
1.2Der Weg zu GitOps
1.2.1Traditionelle Silos
1.2.2DevOps
1.2.3Infrastructure as Code
1.2.4Kubernetes
1.2.5OpenGitOps
1.3Die vier Prinzipien
1.3.1Prinzip 1: Deklarativ
1.3.2Prinzip 2: Versioniert und unveränderlich
1.3.3Prinzip 3: Automatisch bezogen
1.3.4Prinzip 4: Kontinuierlich angeglichen
1.4Fragen und Missverständnisse
2Welchen Unterschied macht GitOps?
2.1Indizien aus den DORA-Studien
2.2Der Unterschied im Alltag: Geschichten eines Entwicklungsteams
2.3Szenario
2.3.1Repositories
2.3.2Deployment-Fluss
2.3.3Vergleichsszenario »Mit GitOps«
2.4Kontinuierlich nach Dev deployen
2.5Ressourcen aufräumen
2.6Grenzfälle in CI vermeiden
2.7Ressourcen wiederherstellen
2.8Konfigurationsänderungen ausrollen
2.9Incidents navigieren
2.10Zielsysteme besser absichern
3Wie fange ich mit GitOps an?
3.1Agile Empfehlung: zügiger Durchstich
3.2Fragen zur Orientierung
3.3Eine Beispielimplementierung mit Argo CD
3.3.1Zielsetzung
3.3.2Voraussetzungen
3.4Schritt 1: Einen Cluster starten
3.5Schritt 2: Argo CD installieren
3.5.1Ressourcentypen von Argo CD verstehen
3.6Schritt 3: Eine eigene Application erzeugen
3.7Schritt 4: Eine Änderung deployen
3.8Fazit
Teil IIPraxis
4Argo CD oder Flux auswählen
4.1Zahlen und Fakten
4.2Bootstrapping
4.3Linking
4.4CLI und GUI
4.5Komponenten und Ressourcenbedarf
4.6Authentifizierung und Autorisierung
4.7Templating
4.8Configuration Management
4.9Monitoring und Alerting
4.10Ökosystem
4.11Mandantentrennung
4.12Multi-Cluster-Management
4.13OCI statt Git
4.14Hochverfügbarkeit und Lastverteilung
4.15Reifegrad
4.16Kommerzielle Angebote
4.17Fazit und Tipps zur Entscheidungsfindung
5Secrets sicher verwalten
5.1Secrets lagern und verwalten
5.1.1Secrets verschlüsselt im Repo speichern
5.1.2Secrets extern verwalten
5.2Secrets konsumieren
5.2.1Secrets als native Kubernetes-Secrets konsumieren
5.2.2Secrets über Sidecar-Container injizieren
5.2.3Secrets über ein CSI-Volume konsumieren
5.3Wir erweitern die Beispielimplementierung
5.3.1Ziele
5.3.2Datenfluss von HashiCorp Vault über ESO in den Cluster
5.3.3Schritt 1: Das Config-Repo bootstrappen
5.3.4Schritt 2: Anwendungen in neuen Namespace deployen
5.3.5Schritt 3: ESO mit HashiCorp Vault verbinden
5.3.6Schritt 4: Beispiel-Secret erstellen
5.3.7Schritt 5: Das Secret integrieren
5.3.8Schritt 6: Das Secret ändern
5.4Fazit
6Repositories und Ordner strukturieren
6.1Design des GitOps-Prozesses
6.2Kategorien von GitOps-Patterns
6.3Operator Deployment Patterns
6.3.1Instance per Cluster
6.3.2Hub and Spoke
6.3.3Instance per Namespace
6.4Repository Patterns
6.4.1Monorepo
6.4.2Repo per Team
6.4.3Repo per Application
6.4.4Repo per Environment
6.5Promotion Patterns
6.5.1Branch oder Folder per Environment
6.5.2Preview Environments
6.5.3Global Environments oder Environment per Application
6.5.4Configuration Management
6.5.5Config Update
6.6Verdrahtungs-Patterns
6.6.1Bootstrapping
6.6.2Linking
6.7Beispiele für Config-Repos
6.7.1Beispiel 1: Argo CD Autopilot
6.7.2Beispiel 2: GitOps Playground
6.7.3Beispiel 3: Flux Monorepo
6.7.4Beispiel 4: Flux Repo per Team
6.7.5Beispiel 5: The Path to GitOps
6.7.6Beispiel 6: Environment-Varianten
6.8Mandantentrennung
6.8.1Rolle der GitOps-Operatoren
6.8.2Rolle der Repo-Struktur
6.8.3Rolle der Cluster
6.8.4Teams und Environments trennen
6.9Fazit
7Asynchron deployen
7.1Deployment-Flüsse
7.1.1Schritte
7.1.2Kombinationen von Zuständigkeiten
7.1.3Deployment-Fluss 1: CIOps
7.1.4Deployment-Fluss 2: Schmal-GitOps
7.1.5Deployment-Fluss 3: CI-Klammer
7.1.6Deployment-Fluss 4: Übergabe
7.1.7Deployment-Fluss 5: GitOps-geführt
7.2Rollout durch den GitOps-Operator
7.2.1Rollout-Schritte im GitOps-Operator
7.2.2Timing und Koordination der Rollout-Schritte
7.2.3Intervalle der Rollout-Schritte
7.2.4Rollout im GitOps-Operator aktiv triggern
7.3Config Update
7.3.1Argo CD Image Updater
7.3.2Flux Image Automation
7.3.3Dependency-Bot
7.4Prüfen
7.4.1Prüfen via CI-Server
7.4.2Prüfen via GitOps-Operator
7.4.3Progressive Delivery
7.5CI-Server mit GitOps verwalten
7.6Fazit
8Alerting integrieren
8.1Gesundheitszustand feststellen
8.1.1Kubernetes-nativ mit kstatus
8.1.2Helm-Hooks
8.1.3Flux
8.1.4Argo CD
8.2Benachrichtigungen verschicken
8.2.1Flux
8.2.2Argo CD
8.3Ganzheitliche Herangehensweise
9Imperativ eingreifen
9.1Eindeutig ausgeschlossene Aktionen
9.2Risiken und Chancen
9.3Einen Debug-Pod starten
9.4Ein Backup wiederherstellen
9.5Ein Deployment neu starten
9.6Ressourcen neu erzeugen
9.7Ein Deployment skalieren
9.8Fazit
Teil IIIWeiterführendes
10Mehrere Cluster verwalten
10.1Single-Cluster vs. Multi-Cluster
10.2Cluster API
10.3Konzept von Cluster API
10.4Definition der Cluster API-Ressourcen
10.5Installation des Management-Clusters
10.5.1Provider konfigurieren und temporären Management-Cluster bauen
10.5.2Worker Cluster anlegen
10.5.3Installation des Cluster API Operators
10.5.4Deklarative Installation des Management-Clusters
10.6Verwaltung von Workload-Clustern mit Argo CD
10.7Fazit
11Infrastruktur verwalten
11.1Terraform
11.1.1Ein kurzes Tutorial zum Einstieg
11.1.2Grundbausteine von Terraform
11.1.3Terraform vs. OpenTofu
11.1.4Terraform und GitOps
11.1.5Eine EC2-Instanz verwalten mit TF-Controller und Flamingo
11.2Pulumi
11.2.1Grundbausteine von Pulumi
11.2.2Eine EC2-Instanz verwalten mit Pulumi Kubernetes Operator
11.3Crossplane
11.3.1Grundbausteine von Crossplane
11.3.2Eine EC2-Instanz verwalten mit Crossplane
12GitOps außerhalb von Kubernetes
12.1Aus den GitOps-Prinzipien folgende Verantwortlichkeiten
12.2Infrastructure-as-Code-Formate
12.3Weitere GitOps-Operatoren
12.4Features von GitOps-Operatoren
12.5Einen eigenen GitOps-Operator bauen
12.6Eigene GitOps-Operatoren aus der Praxis
12.6.1Docker Swarm und Ansible
12.6.2Helmfile
12.6.3Lektionen
Teil IVAnhang
Nachwort
Index
Hand aufs Herz: Wo schaust du zuerst nach, wenn du wissen möchtest, welche Anwendungen konkret in einem Environment deployt sind? Vielleicht findest du dich in einer der folgenden Antworten wieder:
»Im Cluster selbst – wir deployen nur manuell … «
»In den letzten Deploy-Pipelines vom CI-Server.«
»In einem Git-Repo.«
GitOps kann dich in die Lage versetzen, die letzte der drei Antworten zu geben – und zwar mit sehr großer Zuversicht. Diese psychologische Sicherheit ist nur eines der Resultate von einem Deployment-Workflow auf GitOps-Basis.
In diesem Kapitel stellen wir GitOps ganz grundlegend vor. Dabei starten wir mit einer vagen Gegenüberstellung, um eine grundsätzliche Vorstellung von GitOps zu haben. Dann wollen wir die Hintergründe und Herausforderungen verstehen, aus denen GitOps entstand. Anschließend wenden wir uns den vier Prinzipien von OpenGitOps zu, die GitOps im Kern definieren.
Begriffe und Synonyme
»GitOps-Operator« und »GitOps-Controller« werden fast synonym eingesetzt. Darüber hinaus gibt es noch den Begriff »GitOps-Agent« im Sinne von GitOps-Prinzip 4 (siehe Abschnitt 1.3.4 auf Seite 20). In diesem Buch verwenden wir aus Gründen der Einheitlichkeit den Begriff »GitOps-Operator«, auch wenn der von Kubernetes abstrahierte Begriff »GitOps-Agent« an vielen Stellen passender wäre. In der Praxis wird »GitOps-Operator« unserer Erfahrung nach auch am häufigsten verwendet. Allerdings wird auch im Kontext von GitOps gelegentlich der Begriff »Controller« benutzt. Unser Verständnis ist, dass »Controller« der allgemeinere Begriff ist. Unter »Operator« verstehen wir einen speziellen »Controller« samt seiner Erweiterungen der Kubernetes-API (CRDs). GitOps-Operatoren wie Flux und ArgoCD bieten umfangreiche CRDs an, insofern wirkt dieser Begriff für uns am besten passend. Sowohl Argo CD als auch Flux bestehen aus mehreren Komponenten, die teilweise als »Controller« bezeichnet werden. Unter GitOps-Operator verstehen wir in diesem Kontext die Gesamtheit dieser »Controllers«. Flux ist also ein GitOps-Operator, der aus Kustomize-Controller, Helm-Controller, Notification-Controller etc. besteht.Mit »Config« meinen wir beispielsweise Kubernetes-Ressourcen. Manche verwenden auch den Begriff »Infrastructure as Code« synonym. Andere sehen zwischen Config und Infrastruktur (beispielsweise virtuelle Maschinen) klare Unterschiede.CIOps: Der CI-Server deployt in den Cluster.
Bei einer »klassisch« umgesetzten Pipeline für Continuous Deployment (CD) führt der CI-Server aktiv das Deployment in die Zielumgebung durch (Push-Prinzip). In Abb. 1–1 sehen wir ein Beispiel davon: Der CI-Server, in diesem Fall GitLab CI, verbindet sich mit einem Source Code Management (SCM), zum Beispiel GitHub. GitLab CI lädt ein Git-Repository herunter, das beispielsweise Kubernetes-Manifeste enthält. Anschließend verbindet es sich mit einem Kubernetes-Cluster (beispielsweise über eine Kubeconfig-Datei) und rollt diese Manifeste aus (beispielsweise mit einem kubectl apply). Dieses Verfahren bezeichnen wir als »CIOps1«, weil ausschließlich der CI-Server operativ tätig ist.
Punktuelle Rollouts ermöglichen massiven Drift.
CIOps hat sich jahrelang in der Praxis bewährt – aber es weist an kritischen Stellen entscheidende Mängel auf: Der Rollout wird nur punktuell ausgeführt. Dadurch entsteht ab der ersten Sekunde nach dem CI-geführten Rollout etwas, das alle Infrastruktur-Menschen fürchten: Drift – die Realität entfernt sich mit jedem Moment mehr vom ursprünglich definierten Wunschzustand. Danach manuell ausgeführte Änderungen bleiben intransparent bestehen. Solche Änderungen können aus Versehen passieren oder absichtlich, etwa durch Angreifende. Und genau dadurch entsteht das Problem, das wir am Anfang des Kapitels angerissen haben: Wer eine Woche lang keinen Commit auf das Repo macht, von dem aus die Pipeline getriggert wird, kann eine Woche lang manuelle Änderungen im Cluster machen, und es wird keinerlei automatisches Zurücksetzen auf den in Git definierten Zustand (Reconciliation) geschehen.
Abb. 1–1Die »klassische« CIOps Pipeline
Der CI-Server braucht hochprivilegierten Zugriff auf den Cluster.
Außerdem haben wir gravierende Sicherheitsrisiken: Der CI-Server braucht privilegierten Zugriff auf die Zielumgebung. Meistens bekommt der CI-Server direkt administrativen Zugriff und kann dadurch in den falschen Händen viel Schaden anrichten. Das öffnet sehr gefährliche Einfallstore für Angreifer.
Der CI-Server braucht Sichtkontakt zum Cluster.
Ebenso ist ein Rollout nur dann möglich, wenn eine Netzwerkverbindung vom CI-Server zum Zielsystem besteht. Selbst wenn wir die Rollout-Pipeline im CI-Server automatisch alle 5 Minuten ausführen lassen, wird die Angleichung nur dann passieren, wenn der CI-Server den Cluster erreichen kann.
Außerdem ist in Enterprise-Umgebungen diese Verbindung zwischen Entwicklungsumgebung (CI-Server) und Betriebsumgebung (Kubernetes) aufgrund unterschiedlicher Sicherheitszonen oft eine Herausforderung. Dies kann die Verbindung unmöglich machen oder durch die Notwendigkeit von Firewall-Freischaltungen deutlich erschweren. Zwar unterliegen die umgekehrten Netzwerkverbindungen von der Betriebsumgebung auf die Entwicklungsumgebung (SCM) gegebenenfalls ähnlichen Problematiken. Unserer Erfahrung nach ist es aber meist einfacher, aus der produktiven Betriebsumgebung heraus, als in sie hineinzukommen. Mit GitOps ließe sich selbst dieses Problem lösen: Der GitOps-Operator könnte die Manifeste auch aus einer Open Container Initiative (OCI) Registry lesen, auf die Kubernetes aufgrund der Images ohnehin Zugriff braucht (siehe Abschnitt 4.13 auf Seite 90).
Kein Git-basiertes Löschen
Weiterhin sind wir ziemlich eingeschränkt, weil wir über das Git-Repo, von dem aus der CI-Server deployt, nur bestehende Ressourcen aktualisieren oder neue Ressourcen deployen können. Das Löschen von Ressourcen hingegen ist nicht von Haus aus über Commits möglich (beispielsweise durch das Löschen einer Manifest-Datei), nur über manuelles Eingreifen oder zusätzliche Pipelines.
Geringe Auditierbarkeit durch imperative Änderungen
Die Pipelines des CI-Servers ermöglichen imperative Änderungen an der Config. Typischerweise schreibt man hier den Tag des aktuellen Images in die Config. Gängig ist aber auch das Einfügen von Secrets aus dem Credentials-Store des CI-Servers, das Spezifizieren von Helm-Charts oder das Setzen von umgebungsspezifischen Parametern. Dies führt dazu, dass die tatsächlich an den Cluster übertragene Config nur transient auf dem CI-Server besteht. Damit sind Änderungen nicht einfach nachvollziehbar und Fehler schwerer zu finden.
GitOps: Der Operator im Cluster deployt.
Wie können wir diesen Problematiken begegnen? Kann es überhaupt einen anderen Weg geben? Mit GitOps können wir ganz anders vorgehen (siehe Abb. 1–2): Der CI-Server verschwindet bei einem Rollout grundsätzlich komplett aus dem Bild. Stattdessen gibt es einen Prozess innerhalb des Zielsystems, der ununterbrochen das relevante Git-Repository pullt und auf Änderungen überprüft (Pull-Prinzip). Dieser Prozess wird »GitOps-Operator« genannt; im Diagramm ist es Argo CD.
Abb. 1–2Einfaches Deployment mittels GitOps
Damit können wir den eben genannten Schwierigkeiten bei CIOps sehr gut begegnen:
Selbstheilung durch Continuous Operations
kontinuierliches Ausrollen
: Wir verringern den Zeitraum drastisch, in dem Drift auftreten kann, weil die Manifeste im Git-Repository beständig gelesen und angewandt werden. Bei manuellen Änderungen sorgt der GitOps-Operator also für
Selbstheilung
. Prinzipiell implementiert GitOps das Deployment, insofern kann man es als
Cloud-Native Continuous Deployment
(oder Cloud-Native Continuous Delivery) verstehen. Als Fortführung des Gedankens von Continuous Deployment können wir an dieser Stelle auch von
Continuous Operations
sprechen.
bessere Sicherheit
: Da der GitOps-Operator im Cluster läuft, muss netzwerktechnisch gesehen kein administrativer Zugriff von außerhalb des Clusters mehr erfolgen.
Außerdem zwingt uns die deklarative Natur von GitOps dazu dedizierte Werkzeuge zum Secrets Management zu verwenden, statt diese im CI-Server zu verwalten (siehe Kapitel 5 auf Seite 97). Dies reduziert das Sicherheitsrisiko, das CI-Server darstellen.
höhere Stabilität
: Der GitOps-Operator wendet die Manifeste beständig an. Selbst dann, wenn das SCM kurzzeitig nicht erreichbar ist, kann der GitOps-Operator über den lokal zwischengespeicherten Klon des Repositorys weiterhin einen Rollout der zuletzt gesehenen Manifeste durchführen und Drift eliminieren.
Löschen per Commit
: Durch geschicktes Interpretieren der Git-Historie ist der GitOps-Operator in der Lage, in Git gelöschte Ressourcen auch im Cluster zu löschen. (Dieser Vorgang wird auch als »Pruning« bezeichnet.)
deklarative Beschreibungen und Auditierbarkeit
: Der GitOps-Operator kann nur die finalen Manifeste anwenden, keine imperativen Änderungen vornehmen. Dies zwingt uns dazu, rein deklarativ zu arbeiten, was zu klar nachvollziehbarer Config und Historie führt. Im Nachhinein können wir durch die Historie unserer Commits klar nachvollziehen, wer wann was geändert hat. Im Idealfall beantwortet die Commit-Message auch das Warum.
Weitere Vorteile von GitOps-Operatoren
Über die Behebung der Schwierigkeiten von CIOps hinaus bieten GitOps-Operatoren noch weitere Vorteile:
Skalierbarkeit
: Wenn wir mehrere Instanzen von etwas betreiben wollen, beispielsweise eine Anwendung in mehreren Clustern, skaliert dies mit GitOps besser: Wir können die Config zentral in einem Repo ablegen. Aus diesem können sich dann entweder mehrere GitOps-Operatoren bedienen oder wir verwenden GitOps-Features wie das
ApplicationSet
(siehe
Abschnitt 3.3
auf
Seite 51
), um auf mehrere Zielumgebungen zu deployen.
Innovationen
: Aus der Entwicklung der GitOps-Operatoren sind einige Features hervorgegangen, die über die Grundaufgabe von GitOps hinausgehen. Mit diesen können wir unsere Prozesse noch weiter verbessern. Zu diesen Innovationen zählen unter anderem das bereits genannte
ApplicationSet
für bessere Skalierbarkeit sowie das Lesen von Manifesten aus OCI-Registries zur Vereinheitlichung des Toolings und Vereinfachung der Netzwerkzugriffe.
Außerdem können grafische Oberflächen wie die von Argo CD (siehe Kapitel 3 auf Seite 47) die Developer Experience erhöhen, den Einsteig in Kubernetes vereinfachen und manuelle Interaktion mit dem Cluster verringern.
Mit Preview Environments können wir einfacher mehrere Features gleichzeitig in produktionsnahe Umgebungen bringen (siehe Abschnitt 6.5.2 auf Seite 157).
Den User, der in beiden Bildern nur am Rand auftaucht, haben wir bisher noch komplett außen vor gelassen. In beiden Bildern ist er nur als jemand abgebildet, der Pushes in ein Repo ausführt. Wir werden uns in Kapitel 2 auf Seite 25 genauer damit auseinandersetzen, welche Auswirkungen die Umstellung auf GitOps für die Menschen bedeutet, die damit arbeiten.
Die vier Prinzipien
Wir stellen jetzt direkt die offiziellen vier GitOps-Prinzipien vor, damit wir sie bereits einmal gesehen haben. Sie werden uns durch das ganze Buch begleiten, und wir werden sie in Abschnitt 1.3 auf Seite 16 im Detail beleuchten. Dies sind die GitOps-Prinzipien:
deklarativ
: Der Soll-Zustand eines durch GitOps verwalteten Systems muss deklarativ beschrieben sein.
versioniert und unveränderlich
: Der Soll-Zustand wird in einer Weise gespeichert, die Unveränderlichkeit sowie Versionierung erzwingt und die vollständige Historie erhält.
automatisch bezogen
: Software-Agenten beziehen den beschriebenen Soll-Zustand automatisch.
kontinuierlich angeglichen
: Software-Agenten beobachten den tatsächlichen Systemzustand und versuchen kontinuierlich, ihn dem Soll-Zustand anzugleichen.
Diese GitOps-Prinzipien klingen anfangs sehr abstrakt; sie sind aber keinesfalls in einem rein akademischen Setting entstanden. Wir befassen uns jetzt mit dem Kontext, in dem GitOps entstand.
In den Wasserfall-Methoden konservativer Unternehmen war es üblich, dass Entwicklungsteams, Quality Assurance (QA) Engineers und Betriebsteams strikt voneinander getrennt arbeiteten (siehe Abb. 1–3). Leitende geben einen starren Zeitplan vor, in dem diese drei separierten Teams gemeinsam Software mit geschäftskritischen Features ausliefern müssen – allerdings ohne wirklich miteinander kollaborieren zu können: Entwickelnde bekommen Vorgaben und implementieren diese als Software. Danach übergeben sie den Staffelstab an das QA-Team, das die Software ausführlich testet. Anschließend findet die finale Übergabe an das Betriebsteam statt, die schließlich eine Software ausrollen, die für sie eine völlige Blackbox ist.
Abb. 1–3Drei getrennte Teams: Entwicklung, QA und Betrieb
Nach Funktionen separierte Teams liefern langsam, fehleranfällig und ineffizient.
Dieser Prozess war grundsätzlich sehr langsam und hochgradig anfällig für Fehler, weil Kommunikation und Kollaboration zwischen den Teams nicht gefördert wurde. Da jede Phase dieses Entwicklungsvorgangs oft viele Wochen lang dauerte, war ein schnelles Beheben von Problemen in Produktion kaum möglich und Fehler kostspielig.
Die häufigsten Konflikte traten zwischen Entwicklungs- und Betriebsteam auf im Spannungsfeld zwischen Innovation und Stabilität: Während Entwickelnde unter dem Druck ihrer Vorgaben so schnell wie möglich neue Features liefern wollten, wollte das Betriebsteam Änderungen um jeden Preis vermeiden, um die Verfügbarkeit ihrer Anwendungen zu gewährleisten. Statt die wertvolle Erfahrung sowie Sichtweisen der anderen Teams zu verstehen und voneinander zu lernen, entwickelten sich schnell auch zwischenmenschlich tiefe Gräben zwischen den Abteilungen.
Zwar fing Automatisierung an, eine zunehmende Rolle zu spielen, weil dadurch manuelle Schritte wie ein Build oder ein Deployment deutlich stabilisiert und beschleunigt werden konnten. Dennoch waren diese Verbesserungen immer noch auf nur ein Team jeweils beschränkt. Wir mussten einen anderen und besseren Weg finden.
DevOps: Crossfunktionale Teams mit gemeinsamer Verantwortung
Im Zuge von Agile begannen Organisationen bereits zunehmend, Silos abzubrechen und Kollaboration zwischen getrennten Teams zu fördern. Eine Kultur namens DevOps2 entstand in diesem Kontext, und diese Kultur zielt auf crossfunktionale Teams ab, wie wir in Abb. 1–4 sehen: Teams sind nicht mehr nach Funktion separiert, sondern Entwickelnde, QA Engineers und Betriebler übernehmen eine gemeinsam geteilte Verantwortung (oftmals beispielsweise für ein einzelnes Softwareprodukt). Feedback, Automatisierung und Qualität von Anfang an einzubauen sind wichtige Werte für jedes Team.
Abb. 1–4Teamorganisationen traditionell vs. mit DevOps
In einem solchen Umfeld kann es einem Developer nicht mehr egal sein, ob die Anwendung unperformant in Produktion läuft. Ebenso kann ein Betriebler nicht länger Deployments mit Instabilitätssorgen blockieren. Alle haben eine gemeinsame Verantwortung und lernen deshalb voneinander, was in der jeweiligen Rolle wichtig ist.
Geschwindigkeit und Stabilität stehen nicht mehr im Widerspruch
Dank dieser Fokussierung und Kollaboration und durch hochgradige Automatisierung sind kurze Feedbackzyklen und zügiges Deployen nicht länger ein ferner Wunschtraum. Mittels Continuous Integration (CI) wird auf jedem Commit im Standardbranch eine Pipeline ausgeführt, die den Code testet und einen Build durchführt, an dessen Ende ein deploybares Artefakt steht (beispielsweise ein Java Archive (JAR) oder ein Container-Image)3. Mit Continuous Delivery (CD) als nächster Stufe wird das in CI gebaute Artefakt automatisch auf ein Environment deployt, Integrationstests werden ausgeführt und bei Erfolg wird ins nächste Environment deployt bis direkt vor Produktion. Bei Continuous Deployment (ebenfalls mit CD abgekürzt) wird selbst das Deployen nach Produktion vollständig automatisiert.
Weil Cloud Computing und SaaS-Dienste im Laufe der Zeit zunehmend genutzt wurden, gewannen Themen wie Self-Service und dynamische Infrastruktur an Bedeutung. Im Gegensatz zur »Eisenzeit«, in der man zum Deployen physische Hardware im On-Premises-Rechenzentrum benötigte, konnten wir nun im Cloud-Zeitalter mit sehr geringen Hürden nach Belieben virtuelle Infrastruktur erstellen und wieder abreißen4. In diesem Kontext entstand die Praxis von Infrastructure as Code (IaC).
Infrastruktur wird mit den gleichen Methoden wie Code behandelt.
Wie der Name anklingen lässt, behandelt IaC die Infrastruktur, die zum Deployen von Code benötigt wird, mit ähnlichen Methoden, wie der Code selbst behandelt wird: Statt manuell sich mit Servern zu verbinden und Änderungen durchzuführen, werden Änderungen an Code gemacht, dieser wird committet, eine Pipeline führt Tests aus und rollt diese Änderungen automatisiert aus.
Geringere Hürden, »Operations by PR«
Mit dieser Herangehensweise sind Änderungen an der Infrastruktur mit weniger Hindernissen verbunden. Sowohl Entwickelnde als auch Betriebler haben ein einheitliches Format, um über Infrastruktur zu diskutieren, und können kollaborativ an Infrastruktur arbeiten, wo es nötig ist. Selbst kleine Änderungen an Infrastruktur-Code können genauso leicht wie große Änderungen durch Pull Requests (PRs) durchgeführt werden, was iterative Herangehensweisen an Infrastrukturaufgaben fördert.
Pull/Merge Requests
Manche SCMs nennen es »Pull Request« (PR), andere »Merge Request« (MR). Wir meinen damit in jedem Fall denselben Mechanismus, der einen Feature Branch als »Änderungsanfrage« bereitstellt, die bei Annahme in den Standardbranch gemergt und (im Fall von CD) direkt ausgerollt wird. Wir verwenden der Einfachheit halber in diesem Buch immer den Begriff »Pull Request«.
Deklarativer Code beschreibt nur den Zielzustand.
Bei dem Code, der IaC ausmacht, gibt es allerdings deutliche Unterschiede zu konventionellem Anwendungscode: Meist ist er nicht imperativ, sondern deklarativ. Imperativer Code beschreibt,wie etwas ausgeführt werden soll. Deklarativer Code hingegen beschreibt,was für ein Zielzustand erreicht werden soll.
Ein einfaches Beispiel zur Illustration ist die Gegenüberstellung von jQuery und CSS: Mit jQuery können wir beispielsweise ein bestimmtes Element mit einer bestimmten ID rot einfärben:
Listing 1–1Imperatives Einfärben mit jQuery
1
$(document).ready(function(){
2
$("p").on({
3
mouseenter: function(){
4
$(this).css("color", "red");
5
}
6
});
7
});
Dabei führen wir einen JavaScript-Befehl aus – das ist ein imperatives Vorgehen. Dasselbe Ergebnis können wir mit CSS erreichen, indem wir in einem Block unseren Wunsch ausdrücken, dass alle gewünschten Elemente beim Hovern rot eingefärbt werden:
Listing 1–2Deklaratives Einfärben mit CSS
1
p:hover {
2
color: red;
3
}
Deklaratives IaC
IaC gibt es sowohl in imperativer Form (beispielsweise als Ansible-Playbook oder Chef Infra Cookbook) als auch in deklarativer Form (zum Beispiel als Kubernetes-Manifeste oder Terraform-Dateien). Für den Fokus dieses Buches gilt: Wenn wir von IaC schreiben, dann meinen wir ausschließlich deklarative Formen von IaC, weil nur diese im Kontext von GitOps nutzbar sind.
Diese deklarative Formulierung hat einige Vorteile:
Der Code ist leichter zu lesen, weil die Absicht eindeutiger ist.
Der Code ist leichter weiterzuentwickeln, weil wir kein Wissen über die konkrete Implementierung benötigen.
Optimierungen an der dahinterliegenden Implementierung (beispielsweise hinsichtlich Performance) kommen uns im Hintergrund unmittelbar zugute, ohne dass wir selbst dafür tätig werden müssen.
Bei IaC wird genau das gleiche Prinzip von Deklarationen verwendet: Statt ein Shell-Skript zu nutzen, definieren wir unseren Wunschzustand beispielsweise in Terraform-Dateien, Pulumi-Code, Kubernetes-Manifesten oder Docker-Compose-Dateien. Dadurch ernten wir bei Infrastruktur-Code ganz ähnliche Vorteile wie eben bei CSS beschrieben.
Deklarationen abstrahieren imperative Befehle weg.
Selbstverständlich braucht es zur Umsetzung von deklarativem Code an irgendeiner Stelle auch imperative Befehle. Aber diesen imperativen Code können wir durch Deklarationen elegant wegabstrahieren und mehr Zeit auf wertvolle Infrastruktur-Änderungen investieren. Dieser imperative Code für Infrastruktur muss sich nämlich auch mit vielen Edge Cases befassen:
Konvergenz
: Ist die Ressource bereits im gewünschten Zustand? Ein einmaliger Befehl wird dafür oft nicht ausreichen. Stattdessen müssen mehrere Befehle ausgeführt werden und bei diesen Befehlen muss immer wieder auf erfolgreiche Ergebnisse gewartet werden.
Abhängigkeiten
: Abhängige Ressourcen müssen zuerst erstellt werden. Diese Abhängigkeiten sollten möglichst automatisch erkannt werden.
Idempotenz
: Ein mehrfaches Ausrollen derselben Deklarationen sollte zu einem identischen Ergebnis führen.
Wenn wir Infrastruktur mit IaC verwalten, gehen wir davon aus, dass die eben genannten Punkte grundsätzlich vom Interpreter unserer IaC-Deklarationen (beispielsweise die Terraform-CLI bei Terraform-Manifesten) erfüllt werden. Das letzte Kriterium der Idempotenz wollen wir kurz genauer betrachten:
Idempotenz macht IaC-Rollouts risikofrei.
Idempotente Befehle führen bei wiederholter, sequenzieller Ausführung immer zum gleichen Ergebnis. Ein Negativbeispiel, das Idempotenz nicht erfüllt, wäre der Shell-Befehl echo gitops >> test.txt, weil nach jeder Ausführung eine zusätzliche Zeile in der Text-Datei steht. Der Shell-Befehl echo gitops > test.txt hingegen ist idempotent, weil nach jeder Ausführung das Resultat identisch ist: Immer steht eine einzige Zeile mit dem Inhalt »gitops« in der Text-Datei.
Ein Controller, der IaC-Manifeste ausrollt, muss letztlich imperative Aktionen ausführen, damit unser gewünschter Zustand Realität wird. Wenn jedoch die Aktionen, die er durchführt, so idempotent wie nur möglich sind, dann sind wir in guten Händen, denn ein wiederholter Rollout von Manifesten, in denen sich nichts geändert hat, ist dann vollkommen ungefährlich.
Kubernetes5 ist mittlerweile die am weitesten verbreitete Plattform für Containerbetrieb. Dieses Cluster-Betriebssystem, das aus seiner ursprünglichen Herkunft bei Google 2014 als Open Source zur Verfügung gestellt wurde, hat sich sowohl bei großen Cloud-Providern als auch On-Premises bewährt. Auch wenn keine Plattform alle Anforderungen erfüllen kann, hat Kubernetes einige ganz besondere Eigenschaften.
Eine große Kontrollschleife mit deklarativen Manifesten
Eine dieser Eigenschaften ist, dass deklarative YAML-Manifeste der bevorzugte Weg sind, um mit dem Kubernetes-API-Server (sozusagen dem Backend eines Kubernetes-Clusters) zu reden. Kubernetes arbeitet nämlich mit Controllern, die solche Manifeste entgegennehmen und kontinuierlich dafür sorgen, dass diese »Wunschlisten« Realität werden. Dieses kontinuierliche Konvergieren wird auch als Reconciliation bezeichnet. Kubernetes ist mit seinen Controllern und den zugrunde liegenden Ideen aus der Kontrolltheorie letztlich als eine einzige große Kontrollschleife implementiert.
Kubernetes nimmt also einige der Werte und Praktiken von IaC und setzt sie praktisch um. Und wenn wir zurückdenken an unsere initiale Beschreibung von GitOps, dann wird klar, dass ein GitOps-Operator, der kontinuierlich ein Repo überwacht und dessen Manifeste ausrollt, durch die Grundstruktur von Kubernetes nicht sehr schwer zu implementieren sein sollte.
Und tatsächlich ist es so, dass die beiden großen GitOps-Operatoren Flux und Argo CD, die heutzutage zunehmend genutzt werden, überhaupt erst auf Basis von Kubernetes entstehen konnten. 2014 wurde die Firma Weaveworks gegründet, und sie setzten früh auf Kubernetes als Container-Orchestrator6. 2016 praktizierten Mitarbeiter bereits GitOps, ohne dass es den Begriff überhaupt schon gab, und durch GitOps konnten sie bei einem Incident ihr gesamtes gelöschtes System innerhalb von weniger als einer Stunde wiederherstellen.
2017: Alexis Richardson definiert erstmals GitOps.
Anschließend beschrieb Alexis Richardson im Blogpost »GitOps – Operations by Pull Request« im August 2017 zum ersten Mal die damaligen Prinzipien hinter GitOps und benutzte dafür auch zum ersten Mal das Wort »GitOps«7. Grundsätzlichen sind die meisten der damaligen Prinzipien auch in den heutigen Prinzipien enthalten, allerdings in deutlich verfeinerter Form.
Flux und Argo CD entstehen und reifen.
Dieser Blogpost war auch der Moment, wo Weaveworks ihren GitOps-Operator Flux CD8 vorstellten. Ebenfalls im Jahr 2017 begann bei Intuit die Entwicklung von Argo CD9,10. 2019 wurde Flux in die Cloud Native Computing Foundation (CNCF) aufgenommen, das Argo-Projekt folgte im Jahr 2020. 2020 wurde Flux von Grund auf neu geschrieben und als deutlich reifere und stabilere v2 releast. Im Jahr 2022 erreichten beide Tools den höchsten Reifegrad »Graduated«.
2020: Die GitOps Working Group definiert OpenGitOps.
Aufgrund der rasant wachsenden Einführung von GitOps in der gesamten Industrie bildete sich 2020 eine sogenannte Working Group innerhalb der CNCF, die »GitOps Working Group«. Unter den Gründungsmitgliedern waren Mitarbeiter von Firmen wie Amazon, Azure, GitHub, RedHat und Weaveworks11. Diese Working Group überarbeitete die ursprünglichen GitOps-Prinzipien von Alexis Richardson und erschuf »OpenGitOps«12. Unter diesem Projektnamen wird ein GitOps-Standard erarbeitet und verwaltet, der solide und herstellerneutrale Prinzipien für GitOps gewährt. Im Oktober 2021 wurde die Version 1.0.0 von OpenGitOps und den vier Prinzipien veröffentlicht. Im Jahr 2021 fand auch zum ersten Mal die »GitOpsCon«, eine dedizierte Konferenz zu GitOps, im Rahmen der KubeCon statt.
2023: Zertifizierungen in Vorbereitung
Die GitOps Working Group arbeitet auch weiterhin an der Standardisierung von GitOps. Neben der Bereitstellung von Wissen, Use Cases und Whitepapers, wurde auf der GitOpsCon 2023 das Zertifizierungsprogramm »Certified GitOps Associate (CGOA)«13 im Rahmen der Linux Foundation vorgestellt. Interessierte können sich auf diese Weise GitOps-Wissen aneignen und die Erfüllung der Anforderungen zur Erlangung eines Zertifikats nachweisen. Zudem wird an einem Siegel »Certified OpenGitOps Compliance« gearbeitet, damit Tools in der Lage sind, die definierten OpenGitOps-Standards in ihren Produkten nachzuweisen.
Nun sind wir bei OpenGitOps gelandet und können ungefähr sehen, wie die Herausforderungen, denen wir mit DevOps und IaC begegnen und bei denen uns Kubernetes hilft, uns zu den vier Prinzipien führen, die heutzutage GitOps ausmachen. Im Folgenden stellen wir diese vier Prinzipien vor. OpenGitOps besteht im Kern aus diesen vier Prinzipien und einem zugehörigen Glossar.
Beide Materialien wurden bereits in mehrere Sprachen übersetzt, auch ins Deutsche. Wir würdigen diese Übersetzungsleistung und verwenden die deutschen Begriffe in diesem Buch, an manchen Stellen greifen wir jedoch auch auf die entsprechenden englischen Begriffe zurück, da Englisch im Entwicklungsalltag ein ständiger Begleiter ist.
Wir stützen uns auf OpenGitOps v1.0.014.
Allerdings sind die deutschen Übersetzungen nicht in diesem Release enthalten, deswegen verlinken wir dafür auf konkrete Commits:
die Prinzipien auf Deutsch15das Glossar auf Deutsch16Diese Prinzipien sind anfangs noch sehr abstrakt und schwer vorstellbar. Das ist wichtig, damit sie so wenig wie möglich an eine bestimmte Implementierung oder Plattform gebunden sind. Andererseits ist das nicht hilfreich, weil wir die Konsequenzen daraus nur schwer erfassen können. Deswegen führen wir zuerst jedes Prinzip inklusive seiner Glossareinträge auf und erläutern es anschließend zusätzlich mit eigenen Beschreibungen und Analogien.
»Der Soll-Zustand eines durch GitOps verwalteten Systems muss deklarativ beschrieben sein.«
Glossareintrag »Soll-Zustand«
Die Gesamtheit aller Konfigurationen, die es braucht, um ein sich gleich verhaltendes System wiederherzustellen. Diese Konfigurationen enthalten im Allgemeinen keine gespeicherten Anwendungsdaten wie zum Beispiel Datenbankinhalte, wohl aber die entsprechenden Zugangsdaten für den Zugriff darauf oder Einstellungen für Wiederherstellungs-Tools des Systems.
Glossareintrag »Softwaresystem«
Ein mittels GitOps verwaltetes Softwaresystem beinhaltet:
eine oder mehrere Laufzeitumgebungen, die aus verwalteten Ressourcen bestehenVerwaltungsagenten innerhalb jeder einzelnen LaufzeitumgebungRichtlinien zur Steuerung des Zugriffs sowie der Verwaltung der Repositorys, Deployments und LaufzeitumgebungenGlossareintrag »Deklarative Beschreibung«
Eine Konfiguration, die den gewünschten Soll-Zustand eines Systems beschreibt, ohne Vorgehensweisen zu definieren, wie dieser erreicht wird. Dies erzielt die Trennung der Konfiguration (Soll-Zustand) von der Implementierung (Befehle, API-Aufrufe, Skripte und so weiter), die verwendet wird, um den gewünschten Zustand zu erreichen.
Infrastructure as Code
Wir erkennen an dieser Stelle das Prinzip von deklarativem Arbeiten wieder, das uns in IaC erstmalig begegnet ist. Imperative Deployment-Skripte, die bei CIOps an der Tagesordnung sind, haben bei GitOps keinen Platz. Deklarative Formate hingegen wie HashiCorp Configuration Language (HCL, das Format von Terraform-Dateien), Pulumi-Code, YAML (bei Kubernetes, Docker-Compose, AWS CloudFormation und vielen mehr) und Azure Bicep sind hervorragend geeignet.
Analogie Hausbau
Gerne nutzen wir in diesem Zusammenhang die Analogie eines Hausbaus: Ein Haus kann man selbst bauen, wenn man entsprechend handwerklich begabt ist. Man legt das Fundament auf einem vorher festgelegten Grundstück, baut Mauern, verlegt die Elektrik und natürlich das Dach. Allerdings ist dieser Prozess sowohl sehr langwierig als auch aufwendig. Der Bauherr muss sich in allen genannten Bereichen gut auskennen, damit nicht »gepfuscht« wird.
Im Gegensatz dazu hat der Bauherr aber auch die Möglichkeit, ein Fertighaus bauen zu lassen. Vorab vereinbaren der Bauherr und der Dienstleister einen zu erfüllenden Vertrag. Der Vertrag und die Baupläne enthalten genaue Vereinbarungen über die Anzahl und die Größe der Räume, wie die Räume beheizt oder belüftet werden sowie die Ausstattung der Bäder. Die Aufgabe des Dienstleisters ist es, die Beschreibungen dieses Vertrags in konkrete Pläne umzuwandeln und eigenständig auszuführen.
In dieser Analogie entspricht das Haus dem Softwaresystem, Dienstleister dem GitOps-Operatoren, Bauherren den Entwickelnden (die IaC-Code formulieren) und die Baupläne den deklarativen Beschreibungen.
»Der Soll-Zustand wird in einer Weise gespeichert , die Unveränderlichkeit sowie Versionierung erzwingt und die vollständige Historie erhält.«
Glossareintrag »Zustandsspeicher«
Ein System, um unveränderliche Versionen der Beschreibung des Soll-Zustands zu speichern. Dieser Speicher sollte Zugriffssteuerung und Audits der Änderungen des Soll-Zustands unterstützen. Git, von dem sich der Name GitOps ableitet, ist das kanonische Beispiel für diesen Speicher, aber jedes System, das die genannten Bedingungen erfüllt, kann benutzt werden. In jedem Fall muss der Speicher ordnungsgemäß konfiguriert sein sowie Maßnahmen getroffen werden, um den Anforderungen der GitOps-Prinzipien gerecht zu werden.
In diesem Prinzip sehen wir zum ersten Mal die Anklänge an den Namen »GitOps«. Streng genommen haben wir es an dieser Stelle mit zwei separaten Kriterien zu tun, die aber eng miteinander verknüpft sind: Versionierung und Unveränderlichkeit.
Versionierung ist heutzutage technisch ziemlich einfach zu erzielen: Wir nutzen beispielsweise eine Versionsverwaltung (Git, Mercurial, Subversion) oder alternativ einen Object Store (AWS S3, Azure Blobs, Google Cloud Storage) mit aktivierter Versionierung.
Ohne Unveränderlichkeit kein deterministischer Rollout
Unveränderlichkeit hingegen ist nicht zuallererst ein technisches, sondern ein inhaltliches Kriterium. Es geht nicht primär um Immutable Image-Tags, auch wenn sie bei Prinzip 2 vieles vereinfachen. Stattdessen hilft folgender hypothetischer Test, um zu überprüfen, ob Deklarationen unveränderlich formuliert sind: Wenn ich in der Zukunft dieselben Manifeste erneut ausrolle, wird der Endzustand der gleiche sein?
Negativbeispiele
Schauen wir uns ein paar Beispiele für Inhalte in Deklarationen an, die diesen Test nicht erfüllen:
ein Flux-
HelmRelease
ohne definierte Version (es wird immer die neueste Version genommen)
ein Kubernetes-
Deployment
mit einem Rolling Image-Tag, beispielsweise
nginx:latest
oder
v3
ein Flux-
HelmRelease
mit einer Semantic Versioning (SemVer) Range als Versionsnummer, beispielsweise
10.1.x
eine Referenz auf ein Secret in HashiCorp Vault ohne Versionsangabe (es wird immer die neueste Version genommen)
Auch wenn diese Beispiele alle nicht exakt das Kriterium von Unveränderlichkeit erfüllen, sehen wir dennoch, dass es Unterschiede in den Auswirkungen gibt: Wenn bei den jeweiligen Anwendungen SemVer befolgt wird, dann nimmt die Schwere der Auswirkungen von oben nach unten graduell ab.
Positivbeispiele
Betrachten wir als Kontrast ein paar Positivbeispiele, die vollständig Unveränderlichkeit erfüllen:
ein Flux-
HelmRelease
mit einer fixen Version, beispielsweise
10.1.0
ein Kubernetes-
Deployment
mit einem Immutable Image-Tag (das muss allerdings in der jeweiligen Registry konfiguriert sein)
ein Kubernetes-
Deployment
mit einem Image-Tag
und Digest
, beispielsweise
nginx:latest@sha256:9504f3f64a3f16f0...
eine Referenz auf ein Secret in HashiCorp Vault mit Versionsangabe
Unveränderlichkeit hat ihren Preis.
Je exakter man Versionen pinnt, desto mehr Aufwand entsteht dabei aber auch. Manche Aufwände kann man mit Tools wie Renovate17 automatisieren, aber auch die Instandhaltung davon kommt mit Kosten. Letztendlich ist Unveränderlichkeit also keine binäre Entscheidung, sondern wird immer ein Kompromiss sein. Ist mir ein möglichst exaktes Pinnen einer Version wichtig genug für diese oder jene Ressource – oder kann ich mit einem bestimmten Grad an Nichtdeterminismus leben? Diese Entscheidungen sind letztlich immer eine kontextabhängige Entscheidung, für die es kaum Leitlinien geben kann. Immerhin stößt GitOps uns mit der Nase darauf und fordert uns dazu heraus, diese Entscheidungen bewusst zu treffen.
Analogie Hausbau fortgeführt
Führen wir noch die Analogie des Hausbaus fort: Der Bauherr und der Dienstleister sind mit dem Vertrag und den Bauplänen zum Notar gegangen. Beide Parteien übergeben die Dokumente dem Notar, lassen sich eine Kopie mitgeben, und der Notar verwahrt die originalen Dokumente in einem Safe.
Wenn der Bauherr eine Änderung an den Plänen wünscht, dann schlägt er diese dem Dienstleister schriftlich vor. Ist dieser einverstanden, dann unterschreibt er das Dokument und schickt es an den Notar. Der Notar nimmt das Dokument entgegen, schickt den beiden Parteien Kopien des Dokuments und legt es zur ersten Fassung in den Safe dazu. So haben alle Parteien immer einen aktuellen Stand der Dokumente.
Der Safe beim Notar ist in diesem Fall der Zustandsspeicher (beispielsweise ein Git-Repo), der Änderungsvorschlag des Bauherren entspricht einem PR, das Unterzeichnen des Änderungsvorschlags ist der Approval auf dem PR, die Kopien sind dezentrale, lokale Kopien des Git-Repos und das Ablegen im Safe mit dem Verschicken der Kopien entspricht dem Merge des PR. (Der Notar selbst ist in diesem Fall keine wirkliche entscheidende Entität, aber vielleicht ist er mit dem SCM insgesamt gleichzusetzen, alternativ mit einem CI-Server, der nach dem Durchlaufen einer PR-Pipeline automatisch einen Merge durchführt.)
»Software-Agenten beziehen den beschriebenen Soll-Zustand automatisch.«
Der »Software-Agent« ist nichts anderes als der GitOps-Operator, von dem wir bereits am Anfang des Kapitels gesprochen haben. Dieser lädt die deklarativen Beschreibungen aus dem Zustandsspeicher selbstständig herunter (Pull-Prinzip), beispielsweise indem er in regelmäßigen Intervallen einen git clone ausführt.
Prinzip 3 und 4 lassen sich praktisch nicht trennen.
Prinzip 3 und 4 gehören im Grunde genommen untrennbar zusammen. Dennoch beschreiben sie zwei unterschiedliche Aspekte von »Continuous Operations«: Prinzip 3 legt den Fokus auf das Herunterladen der Manifeste, während Prinzip 4 den Rollout dieser Manifeste beschreibt.
Die Trennung ergibt in der Theorie und für die Eindeutigkeit der Prinzipien Sinn; in der Praxis werden wir jedoch kein System finden, das nur eines dieser beiden Prinzipien erfüllt. Deswegen wenden wir uns direkt Prinzip 4 zu und betrachten es im Verbund mit Prinzip 3.
»Software-Agenten beobachten den tatsächlichen Systemzustand und versuchen kontinuierlich , ihn dem Soll-Zustand anzugleichen.«
Glossareintrag »kontinuierlich«
Mit »kontinuierlich« ist im Kontext der Angleichung gemeint, dass diese regelmäßig, aber nicht zwangsweise sofort erfolgt.
Wenn uns eine sofortige Angleichung wichtig ist, gibt es dennoch Möglichkeiten, die aber mit ihren eigenen Herausforderungen kommen. Diese beleuchten wir in Abschnitt 7.2.4 auf Seite 212 genauer.
Glossareintrag »Angleichung«
Der Prozess, bei dem sichergestellt wird, dass der tatsächliche Zustand eines Systems mit seinem Soll-Zustand übereinstimmt. Im Gegensatz zur traditionellen CI/CD, bei der die Automatisierung im Allgemeinen durch voreingestellte Auslöser gesteuert wird, wird bei GitOps die Angleichung immer dann ausgelöst, wenn eine Abweichung vorliegt.
Die Abweichung kann darauf zurückzuführen sein, dass sich der Ist-Zustand unbeabsichtigt geändert hat oder dass eine neue Version der Soll-Zustands-Beschreibung vorliegt. Auf der Grundlage von Richtlinien und Feedback des Systems sowie früherer Angleichungsversuche werden Maßnahmen ergriffen, um die Abweichung im Laufe der Zeit zu verringern.
Glossareintrag »Abweichung«
Abweichung bezeichnet eine (beginnende) Entfernung des Ist-Zustandes eines Systems vom gewünschten Soll-Zustand.
Glossareintrag »Feedback«
GitOps folgt der Kontrolltheorie und wird in einem geschlossenen Kreislauf betrieben. In der Kontrolltheorie beschreibt die Rückmeldung, wie frühere Versuche, einen Soll-Zustand anzuwenden, den tatsächlichen Zustand beeinflusst haben. Verlangt beispielsweise der Soll-Zustand mehr Ressourcen, als in einem System vorhanden sind, könnte der Software-Agent versuchen, automatisch zu einer vorherigen Version zurückzurollen oder den menschlichen Betreibern einen Alarm senden.
Mit Abweichung ist genau der Drift gemeint, den wir anfangs als die besonders große Gefahr von CIOps identifiziert haben. Hier sehen wir auch Beispiele für Ursachen von Drift: Dies können entweder manuelle Änderungen im Cluster sein, die wir eliminieren wollen und die vom GitOps-Operator rücksichtlos überschrieben werden, oder es können bewusste Änderungen sein, die wir in einem Git-Repo durchgeführt haben und dann vom Agenten ausgerollt werden.
Die Formulierung, dass »Maßnahmen ergriffen werden, um die Abweichung im Laufe der Zeit zu verringern«, passt haargenau zu Beschreibungen, die man über die generelle Arbeitsweise von Kubernetes-Controllern liest. Wir sehen erneut, warum Kubernetes ein exzellentes »Substrat« bildet, auf dem GitOps hervorragend gedeiht.
Analogie Hausbau fortgeführt
Wenden wir uns noch ein letztes Mal der Hausbau-Analogie zu. Der Vertrag zwischen Bauherr und Dienstleister enthält eine besondere Klausel: Der Dienstleister ist verpflichtet, in regelmäßigen Abständen das Grundstück zu begutachten und Änderungen, die seit dem letzten Besuch passiert sind und die den Bauplänen widersprechen, rückgängig zu machen. Dazu könnten selbst verlegte Leitungen, eigens gezimmerte Anbauten, aber auch beschädigte Türen oder zerstörte Fenster zählen. Solche Änderungen werden rigoros beseitigt und müssen stattdessen durch den schriftlichen Prozess durchgeführt werden, wenn sie permanent sein sollen.
Der Bauherr hat sich damit ein zweischneidiges Schwert eingehandelt: Wenn er manuelle Aufwände investiert, werden sie kurz darauf zunichte gemacht werden. An solchen Stellen wird ihn der zusätzliche Aufwand über den Schriftweg ärgern. In den Situationen jedoch, in denen der Dienstleister anstandslos Schäden repariert, wird er sich sehr glücklich schätzen – und dann geht ihm das Beantragen von Änderungen schon viel leichter von der Hand.
In diesem Fall sind die eigenen Anbauten und beschädigten Elemente die Resultate von manuellen Tätigkeiten im Cluster (beispielsweise Installationen von Helm-Charts oder Löschungen von Ressourcen).
Bei Prinzip 1 ist am meisten ersichtlich, wie es aus IaC entstanden ist. Bei Prinzip 2 können wir zumindest noch erkennen, wie eine DevOps-Kultur von gemeinsamer Verantwortung einen auditierbaren Zustandsspeicher bevorzugt. Prinzip 3 und 4 hingegen sind das, was GitOps am meisten zu GitOps selbst macht. Deswegen wird auch die Hausbau-Analogie Schritt für Schritt surrealer, weil es im echten Leben bisher kaum Situationen gibt, für die man eine gute Entsprechung für den Kern von GitOps findet.
An dieser Stelle wollen wir in Kurzform auf einige häufige Fragen eingehen, die sich beim ersten Kontakt mit GitOps stellen:
Kubernetes setzen wir nicht ein. Kann ich trotzdem GitOps nutzen?
Ja! GitOps sind zuallererst die vier Prinzipien, und diese beschränken sich mit keinem Wort auf Kubernetes. Jedoch sind die reifsten und am weitesten verbreiteten GitOps-Operatoren Argo CD und Flux auf Kubernetes ausgelegt. Deswegen beschäftigen wir uns auch den allergrößten Teil dieses Buches mit GitOps im Kontext von Kubernetes. In
Kapitel 12
auf
Seite 333
beleuchten wir aber auch GitOps außerhalb von Kubernetes.
Ist mein Projekt bereit für GitOps?
Ja, höchstwahrscheinlich! Einzige Voraussetzung sind deklarative Beschreibungen (zum Beispiel Kubernetes-Manifeste), die du in einem Zustandsspeicher (zum Beispiel einem Git-Repo) speicherst.
Muss ich Anwendungscode und Deklarationen zwingend in separaten Repositories lagern?
Nein. Die Praxis, Code und Config zu trennen, hat sich zwar an vielen Stellen bewährt, und wir halten dieses Vorgehen auch in vielen Situationen für angemessen. Es kann jedoch auch Gründe geben, diese nicht zu trennen. In
Abschnitt 6.4.3
auf
Seite 141
besprechen wir Gründe für und wider und zeigen Kompromisse auf.
Wie integriere ich GitOps in meine existierende CI/CD-Pipeline?
In
Kapitel 3
auf
Seite 47
arbeiten wir als Einstieg ein grundlegendes Tutorial zur Installation eines GitOps-Operators und zum Arbeiten mit einem Config-Repo durch. Bestehende Pipelines, die CIOps implementieren, müssen nicht erweitert werden – sie können sogar gekürzt werden um den Rollout-Schritt. Zusätzliche Schritte vom CI-Server sind nicht nötig, denn der GitOps-Operator führt den Rollout (basierend auf den Manifesten in Git) selbstständig aus. Durch GitOps führen wir Asynchronität in unseren Deployment-Ablauf ein. Die Herausforderungen, die daraus entstehen, betrachten wir eingehend in
Kapitel 7
auf
Seite 197
.
Meine CI/CD-Pipeline überträgt rein deklarative Manifeste unverändert an den Cluster. Ist das GitOps?
Mindestens das Prinzip 4 (kontinuierlich angeglichen) ist dabei nicht erfüllt. Vielleicht hilft es, den Begriff »GitOps« von »Git-basierten« Workflows oder Pipelines abzugrenzen, die zumindest Prinzip 1 und 2 erfüllen. Vor der Einführung der Prinzipien gab es einige Missverständnisse darüber, was genau GitOps bezeichnet. Deswegen sind Artikel und Blogposts über GitOps, die vor der Festlegung der vier Prinzipien veröffentlicht wurden, mit sehr viel Vorsicht zu genießen, weil teilweise Dinge als GitOps bezeichnet werden, die nicht mit den heutigen Prinzipien übereinstimmen. Dennoch ist niemand gezwungen, von ihrem aktuellen Workflow auf GitOps zu wechseln, wenn die Vorteile von GitOps die Einschränkungen des aktuellen Workflows nicht überwiegen.
Wie funktioniert GitOps mit Secrets?
Guter Punkt: Der gesamte Zustand muss bei GitOps deklarativ beschrieben sein, so auch Secrets. Natürlich sollten Secrets nie im Klartext in Git stehen. Die Lösung ist die Verwendung dedizierter Werkzeuge zum Secrets Management. In
Kapitel 5
auf
Seite 97
schauen wir uns verschiedene Optionen für den Umgang mit Secrets im GitOps-Umfeld an.
Kann ich nur Container mit GitOps verwalten?
Nein, du kannst letztlich alles mit GitOps verwalten, das sich deklarativ ausdrücken lässt. Da GitOps sich aus Infrastructure as Code (IaC) entwickelt hat, gibt es momentan vor allem deklarative Formate für das Deployen von Containern (zum Beispiel native Kubernetes-Manifeste), für das Verwalten von Cloud-Infrastruktur (zum Beispiel mit Terraform, Pulumi oder Crossplane, siehe
Kapitel 11
auf
Seite 291
) und für das Verwalten von Berechtigungen (beispielsweise mit Kyverno
18
oder Gatekeeper
19
aus dem Projekt Open Policy Agent).
GitOps besteht im grundsätzlichsten Kern aus den vier Prinzipien, die wir im vorigen Kapitel kennengelernt haben. Dass der offensichtlichste Unterschied zu traditionellen Deployments darin liegt, dass ein Prozess im Zielsystem deployt statt ein CI-Server, ist noch recht klar zu erkennen. Aber oftmals fällt es schwerer, klar zu benennen, zu welchen Konsequenzen GitOps ganz konkret im Alltag eines Entwicklungsteams führt.
Wir wollen dieses Kapitel nutzen, um diese Unterschiede genauer zu analysieren. Dementsprechend werden wir Vergleiche ziehen zwischen Teams, die aus dem CI-Server heraus deployen, und Teams, die GitOpsbasiert Deklarationen laden und kontinuierlich anwenden. Dass (zumindest in einem grundlegenden Maß) Deklarationen wie Kubernetes-Manifeste genutzt werden statt imperativen Befehlen und dass diese Deklarationen in Versionskontrolle verwaltet werden, nehmen wir grundsätzlich als gegeben an.
Den Großteil dieses Kapitels werden wir in den Alltag eines fiktiven Entwicklungsteams eintauchen, um anhand von kleinen Geschichten den Effekt von GitOps besser zu verstehen. Anfangs werden wir allerdings noch einen Blick in die Forschung werfen, um zu untersuchen, ob sich die Effekte von GitOps womöglich auch beziffern lassen.
Für unsere sehr spezifische Fragestellung ist die wissenschaftliche Faktenlage noch sehr dünn. Ein hilfreiches Instrument zur Beurteilung der Effekte von GitOps sehen wir im Bericht »Accelerate State of DevOps 2022« von Google1, der von der Forschungsgruppe DevOps Research and Assessment (DORA)2 erstellt wird. Diese DORA-Studie, die seit 2018 jedes Jahr unter mehreren Zehntausend Berufstätigen durchgeführt wird, untersucht die Themenbereiche Softwarebereitstellung und Betriebsleistung und mögliche zugrunde liegende Faktoren. Der Bericht enthält in der neuesten Fassung von 2022 einige Punkte, die wir als Indizien sehen, dass GitOps-Praktiken positive Effekte auf Teams und Organisationen haben können.
DORA misst die Leistung eines Software-Teams (»Software Delivery Performance«) anhand von fünf Metriken:
Deployment-Häufigkeit
: Wie oft wird Code nach Produktion deployt?
Lieferzeit für Änderungen
: Wie lange dauert es, bis eine committete Codeänderung in Produktion landet?
Fehlerrate bei Änderungen
: Welcher Prozentsatz an Codeänderungen führt zu Beeinträchtigungen und benötigt Wiederherstellungsmaßnahmen?
Wiederherstellungszeit bei Ausfällen
: Wie lange dauert das Beheben von Beeinträchtigungen?
Betriebliche Verlässlichkeit
: Wie oft werden die Erwartungen hinsichtlich Stabilität und Verfügbarkeit erfüllt?
Die Kombination der GitOps-Prinzipien 2 bis 4 ist assoziiert mit höherer Software Performance Delivery.