Im letzten Beitrag haben wir Vor- und Nachteile von Datenbanken auf Kubernetes untersucht. Diesmal steht das wohl größte Thema im Bereich Kubernetes an: Continuous Integration & Delivery (CI/CD). Während die Toolwahl bei der CNCF Landscape dafür ähnlich groß ist, ist der dahinterliegende Workflow einer der umfangreichsten. CI/CD führt alle Bausteine der CNCF Landscape zusammen. Die Zusammenführung aller Komponenten für das Gesamtsystem steht dabei im Fokus.
Was bedeutet CI/CD?
Continuous Integration (CI) behandelt die automatisierte Zusammenführung verschiedener Komponenten während der Softwareentwicklung. Dadurch wird sichergestellt, dass auch bei mehreren Entwicklungen an der gleichen Applikation keine Fehler entstehen. Aufwändige Pull oder Merge Requests können so vermieden werden.
Continuous Delivery (CD) kümmert sich im Anschluss um die automatische Bereitstellung einer neuen Version. Die Voraussetzung ist dabei, dass die Applikation ohne weitere Änderung produktiv einsetzbar ist.
Continuous Deployment ist der letzte Schritt zur Zusammenführung aller Komponenten bzw. der Konfigurationen und derer Installation auf der Laufzeitumgebung. Dies kann je nach Reifegrad die Entwicklungs- oder auch Produktivumgebung beinhalten.
Continuous Delivery und Continuous Deployment sind verschiedene Methoden mit unterschiedlichen Zielstellungen. Sie können aber aufgrund ihrer Ähnlichkeit auch synonym verwendet werden, wie auch in diesem Blogbeitrag.
Dependency Change – und alles ändert sich
Das interessanteste an CI/CD auf Kubernetes ist der Paradigmenwechsel. Die meisten Applikationen für eine CI/CD-Pipeline unterstützen den deklarativen Ansatz. Das bedeutet, dass die gängige imperative Praxis, eine Liste an Aufgaben abzuarbeiten, weniger Bedeutung erhält. Deklaratives Arbeiten vergleicht zwei Zustände miteinander: Den Ist- und den Soll-Zustand. Unterscheiden sich diese voneinander, wird der Soll-Zustand hergestellt.
Dadurch wird die Anpassung oder Installation von Komponenten nachvollziehbarer und berechenbar. Wenn beispielsweise eine Applikation skaliert werden muss, kann man das explizit durch die Angabe einer Mindestanzahl von Pods erreichen. Dabei wird die vollständige Konfiguration vom Repository mit der laufenden Konfiguration verglichen und entsprechend angepasst.
Das betrifft dabei alle möglichen Elemente, zum Beispiel Konfigurationen im Bereich Netzwerk, Backup oder auch der Runtime.
Das setzt voraus, dass alle zu verwaltenden Abhängigkeiten bzw. Komponenten bekannt und prüfbar sind. Mit Hilfe dieser Vorgehensweise lassen sich verschiedene Methoden anwenden, um vor allem die teamübergreifende Arbeit zu verbessern. Die Verknüpfung der Aufgaben und der Teams steht dabei im Fokus.
GitOps und die deklarative Programmierung
Wie sieht nun die Umsetzung aus? Um die Zustände transparent zu vergleichen, benötigt man idealerweise eine “Single Source of Truth”. So kann man sicherstellen, dass jeder in der Lage ist, Unstimmigkeiten zu entdecken und nachzuvollziehen.
Was bietet sich besser dafür an, als ein Git-Repository? Als Applikation für verteilte Softwareverwaltung bietet es die perfekte Grundvoraussetzung. Es bekam sogar seinen eigenen Namen: GitOps. Der Vergleich mit der laufenden Instanz auf Kubernetes anhand der Konfigurationselemente – den Kubernetes-Objekten – ist dadurch möglich.
Das ermöglicht außerdem vollständige Umgebungen darüber zu verwalten. Die typische Toolchain kann dann über ein oder mehrere Repositories integriert werden. Die einzige Voraussetzung ist eine vollumfängliche API für jeden Client der Toolchain.
Um nun die Aufgaben der Integration und der Delivery zu übernehmen, bieten sich verschiedene Möglichkeiten. Sei es mit einer voll definierten Pipeline auf Gitlab, einer Workflow-Definition über ArgoCD oder der klassischen Abarbeitung im Jenkins-Cluster: jede Software bietet verschiedene Vorteile für den Anwender.
Eine Frage des Prozesses, nicht der Software
Wie eingangs erwähnt, stellt sich aber nicht die Herausforderung in der Wahl einer geeigneten Software. In der CI/CD zeigt sich, wie gut im Vorfeld alle Anforderungen bedacht wurden. Hier spiegelt sich als weitere Methode die Adaption des “Shift-Left-Testings” wider. In dieser Methode werden Erkenntnisse aus dem Betrieb eines Systems bereits vor dem Deployment erfasst und analysiert. Dies bedeutet zwar mehr Arbeit während der Entwicklung, aber weniger Nacharbeiten im Regelbetrieb. Und das wiederum weniger Aufwand bei Neuentwicklungen, Migrationen oder anderen Arten der Anpassung.
Das ist schlussendlich auch das Ziel von CI/CD. Die vielen verschiedenen Methoden und Erfahrungen sollen zusammengeführt werden und einfach anwendbar sein. Dabei sollte jede Tätigkeit automatisiert sein, um einen steten Fluss zwischen Code-Entwicklung und Betrieb zu gewährleisten. Fehler sollen vor der Installation auf produktiven Systemen erkannt und behoben werden. Jedes Element ist transparent und dokumentiert.
Wie am Ende all das zusammengeführt wird, entscheidet jedes Team für sich. Denn durch die einheitliche Nutzung von Git-Repositories, YAML-Configs und Kubernetes sind drei wichtige Pfeiler gesetzt, um einen transparenten und nachvollziehbaren Workflow für alle Nutzenden zu erstellen.
Um das meiste aus einer CI/CD herauszuholen, sind wiederum vorhergehende Standards zu etablieren. Da hilft der Themenbereich “App Definition & Image Build”, dem wir uns im nächsten Blogbeitrag widmen werden.
Wer nicht warten kann: Solltet ihr Fragen haben oder bei der Entscheidung Hilfe benötigen, helfen wir euch gern weiter. Wir haben für alle Probleme den richtigen Lösungsansatz. Schreibt uns einfach!