CI/CD-Systeme für Kubernetes unter die Lupe genommen

Kubernetes und seine CI/CD-Generationen

Daniel Bornkessel, Anja Kammer, Jörg Müller

© Shutterstock / FocalPoint

Der neue Kubernetes Cluster ist eingerichtet, die Softwarearchitektur ist ganz modern auf Basis von Microservices geplant, jetzt fehlt nur noch eine Continuous Integration oder Continuous Delivery (CI/CD) Pipeline. Diese ist schnell mit dem Jenkins gebaut, der schließlich schon seit Jahren einen guten Dienst verrichtet. Alles nur noch eine Kleinigkeit, oder? Aber ist das eigentlich eine gute Idee?

Die beschriebene Situation kann häufig beobachtet werden: Firmen brechen alte, schwerfällige Monolithen in Microservices auf und deployen diese auf Kubernetes. Dabei wird oft die alte CI/CD-Infrastruktur beibehalten. Diese passt jedoch nicht mehr wirklich zur neuen Realität: Zwar können mit aktuellen Jenkins-Versionen Pipelines beschrieben werden und Unit-Tests können auch in Bamboo ausschließlich in Containern ausgeführt werden – allerdings wurden diese Systeme ursprünglich mit einer komplett anderen Philosophie entwickelt und passen dementsprechend schlecht zu modernen Anforderungen. Eine Anpassung der alten Systeme gestaltet sich müßig: Maven- oder Java-Plug-ins sind unnötig, wenn zum Bauen von Applikationen einfach ein Docker-Container genutzt werden kann. Kubernetes-Deployments können mit Tools wie kubectl oder Helm in einem Container implementiert werden, statt dafür ein Plug-in für das CI/CD-System zu nutzen. Die Anforderungen an Funktionalitäten, die CI/CD-Systeme selbst zur Verfügung stellen müssen, sinken durch den Einsatz von Docker.

Ein weiterer Anachronismus in Zeiten von Configuration as Code ist die Konfiguration der Pipelines über eine grafische Benutzeroberfläche. Eine solche Konfiguration ist mühsam und die Fehlersuche gestaltet sich schwierig. Aktuelle Systeme nutzen deklarative, textuelle Beschreibungen von Pipelines. Diese können einfach in Versionsverwaltungssystemen hinterlegt werden, zusammen mit der eigentlichen Applikation. So konfigurierte Pipelines können schnell wiederhergestellt werden, sollte das CI/CD-System neu aufgesetzt werden. Die Benutzeroberflächen moderner Systeme bieten nur noch eine Sicht auf den Zustand von Pipelines und ermöglichen das manuelle Starten einzelner Schritte. Ganz neue Lösungen verzichten nicht nur auf das Konzept der Plug-ins, sondern versuchen noch mehr Kernfunktionalitäten von CI/CD-Systemen auszulagern. Kubernetes löst beispielsweise viele Aufgaben, die ehemals von jedem CI/CD-System selbst implementiert wurden. Dazu gehören zum Beispiel das Starten, Stoppen und Verwalten von Containern. Seit der Einführung des ersten populären CI-Systems CruiseControl im Jahr 2001 hat sich CI/CD mehrmals neu erfunden. Die neueste Generation von Systemen ist gerade dabei, Produktionsreife zu erlangen.

Drei Generationen von CI/CD Systemen

Erste Generation: CI als Idee ist mit der agilen Bewegung Anfang der 2000er-Jahre populär geworden. In diesem Zusammenhang entstanden erste Tools wie CruiseControl. Anfangs waren diese Systeme noch recht einfach, entwickelten sich aber schnell zu sehr umfangreichen Lösungen weiter. Zu dieser ersten Generation von Systemen gehören Jenkins, Bamboo und TeamCity von JetBrains. Ein wesentliches Merkmal dieser Systeme ist, dass sie sämtliche Funktionalität selbst implementieren. Sie unterstützen Build-Tools verschiedener Programmiersprachen durch Plug-ins. Um Lasten zu verteilen, unterstützen viele Lösungen die Verteilung auf mehrere Hosts. Auf diesen laufen Agents, die jeweils bestimmte Schritte in einer Pipeline ausführen können. Das Managen ganzer Cluster, auf denen solche Agents laufen, ist oft Teil des CI/CD-Systems. Agents können spezifisch konfiguriert werden, um auch exotische Anforderungen zu erfüllen. Um diese Features zu bedienen, sind sehr umfangreiche und komplexe Weboberflächen nötig. Mit dem Aufkommen von Continuous Delivery wurde noch die Fähigkeit zur Verwaltung von Pipelines in die Tools eingebaut. Die erste Generation bietet also einen großen Funktionsumfang, ohne große Anforderungen an ihr Umfeld zu stellen. Dafür zahlt man allerdings einen hohen Preis: zunehmende Komplexität. Häufig muss deshalb die Konfiguration von einem Experten oder Expertenteams gepflegt werden.

Zweite Generation: Die Systeme der zweiten Generation entstanden unter anderem aus dem Wunsch, diese Komplexität zu verringern. Zwei technologische Trends halfen dabei, diesen Wunsch zu erfüllen. Mit Software as a Service (SaaS) wurde es möglich, den Betrieb und damit auch die Komplexität eines CI/CD-Systems vom Entwicklungsteam fernzuhalten. Dieses kann sich auf die Entwicklung von Software konzentrieren und beschreibt die Schritte zum Bauen der Software in einer Konfigurationsdatei. Die wird von einem System gelesen, interpretiert und in ein ausführbares Skript übersetzt, das anschließend ausgeführt wird. Die Strategie wird Configuration as Code genannt und ist eine zentrale Eigenschaft der zweiten Generation. Neu ist auch, dass das CI/CD-System nicht auf der firmeneigenen Infrastruktur betrieben werden muss. Travis CI hat diese Philosophie für GitHub populär gemacht.

Der zweite große Trend bei diesen Systemen ist die konsequente Nutzung von Docker-Containern zum Bauen und Testen der Software. Dadurch wird das CI/CD-System nur noch zum Orchestrator; weder müssen Build-Umgebungen verwaltet, noch Technologien verschiedener Programmiersprachen direkt unterstützt werden.

Die Kombination dieser beiden Ansätze findet man in sehr vielen der aktuellen CI/CD-Systeme. Typische Vertreter der zweiten Generation sind Travis CI, Gitlab CI, Codeship und die Build-Systeme großer Cloudanbieter wie AWS, Google oder Azure. Einige dieser Systeme werden nicht nur als SaaS-Lösung angeboten, sondern können auch in der eigenen Infrastruktur betrieben werden. Auch diese Generation implementiert das Management der Build Cluster durch Agenten oft selbst. Einige Systeme, wie zum Beispiel Gitlab CI, können bereits Agenten in Kubernetes Clustern betreiben.

Dritte Generation: Die dritte Generation von CI/CD-Systemen ist noch stärker auf Kernfunktionalität reduziert und setzt konsequent auf Kubernetes als Laufzeitumgebung. Sie werden deshalb auch als Kubernetes-native bezeichnet. Oft gehen sie bei dieser Fokussierung noch weiter und setzen neben Kubernetes noch weitere Infrastruktur voraus. So laufen manche Systeme nur bei bestimmten Cloudanbietern oder setzen als Anbieter des Versionsverwaltungssystems Produkte wie GitHub voraus.

Durch diese Fokussierung können sie von vorhandenen Komponenten dieser externen Systeme Gebrauch machen. Kubernetes-native CI/CD-Systeme nutzen Kubernetes-Konzepte wie Jobs und Pods. Diese werden zur Ausführung von Workern und Build-Schritten genutzt. Worker starten ausschließlich dann, wenn eine Build Pipeline ausgeführt werden soll. Bei aktivierter Autoskalierung passt Kubernetes automatisch die benötigten Ressourcen an. Es ist also nicht nötig, ständig genügend Hosts für die CI/CD-Infrastruktur vorzuhalten. Die entstehende Verzögerung durch den Skalierungsprozess ist im CI/CD-Kontext zu vernachlässigen. Beendete Pods müssen je nach Lösung teilweise durch Kubernetes CronJobs aufgeräumt werden, um noch benutzten Arbeitsspeicher freizugeben. All diese Aufgaben mussten frühere CI/CD-Systeme selbst ausführen.

DevOpsCon Istio Cheat Sheet

Free: BRAND NEW DevOps Istio Cheat Sheet

Ever felt like service mesh chaos is taking over? As a follow-up to our previous cheat sheet featuring the most important commands and functions, DevOpsCon speaker Michael Hofmann has put together the 8 best practices you should keep in mind when using Istio.

Prototypisches Kubernetes-native CI/CD-System

In einem CI/CD-System der dritten Generation werden Build Pipelines von Events angestoßen (Event-driven), die meist durch Webhooks das CI/CD-System erreichen. Das Vorhandensein solcher WebHooks kann inzwischen bei vielen Versionskontrollsystemen vorausgesetzt werden und ist eleganter als klassisches Polling. Ein Event kann ein neuer Commit, Pull Request oder ein neues Container-Image in der Registry sein.

Wie in anderen CI/CD-Systemen auch, stößt eine Modifikation des Code-Repositorys die Pipeline an. Der Inhalt des Code-Repositorys wird für die Ausführung der einzelnen Build-Schritte heruntergeladen und in dem jeweiligen Container zur Verfügung gestellt. Für die Durchführung der Builds und Tests werden unterschiedliche Container genutzt, die die Funktionalität für den jeweiligen Schritt mitbringen. Pipeline-Definitionen werden in Form von Konfigurationsdateien zusammen mit der betreffenden Applikation im Code-Repository abgelegt (Abb. 1).

Für das Deployment verfolgen Kubernetes-native CI/CD-Systeme den Ansatz der Pull-basierten Strategie. Statt eine Applikation von außen in den Kubernetes Cluster zu deployen, wird das Deployment innerhalb desselben Clusters ausgeführt, in dem die Applikation laufen soll. Der Service-Account des Pods, der das Deployment ausführt, bekommt dazu die Rechte, die Applikation entsprechend auszurollen. Fände das Deployment hingegen von einem externen System statt, so müssten Geheimnisse wie SSH-Schlüssel oder Kubernetes-Zertifikate auf diesem System vorgehalten werden. Die sichere Verwaltung solcher Geheimnisse zu realisieren ist aufwendig. Die Konfiguration bei einem Pull-basierten Deployment ist somit einfacher und sicherer.

Abb. 1: Beispielhafte Architektur für Kubernetes-native CI/CD-Systeme

Abb. 1: Beispielhafte Architektur für Kubernetes-native CI/CD-Systeme

Im Folgenden werden exemplarisch typische Vertreter von CI/CD-Systemen der dritten Generation oder deren Vorbilder vorgestellt.

Das Vorbild: Concourse

Concourse hat auf Systeme der dritten Generation einen ähnlichen Einfluss wie Travis CI auf Systeme der zweiten Generation hatte. Auch wenn es selbst kein Kubernetes-native-System ist, lohnt sich daher eine nähere Betrachtung. Das Projekt wurde Anfang 2014 gestartet und hat von Anfang an alle Aufgaben in Containern ausgeführt. Concourses Oberfläche ist angenehm anders und ermöglicht die Darstellung sehr komplexer Pipelines. Aktuell ausgeführte Schritte sind animiert. Bei komplexen Pipelines ist es möglich, beliebig hinein und hinaus zu zoomen (Abb. 2).

Abb. 2: Eine Pipeline in Concourse

Abb. 2: Eine Pipeline in Concourse

Wie bei Systemen der zweiten Generation können Pipelines ausschließlich über Konfigurationsdateien erstellt und aktualisiert werden. In Concourse wird dazu ein Kommandozeilentool genutzt. Die Entwickler haben interessante Architekturentscheidungen getroffen, die der Zeit voraus waren. Ein zentraler Baustein von Concourse ist die Resource. Concourse Resources können externe Ein- oder Ausgaben sein. Gibt es eine neue Version einer Concourse Resource, kann sie als Trigger für den Start einer Pipeline genutzt werden. Am Ende eines Pipeline-Schritts wird häufig eine neue Artefaktversion an eine Concourse Resource übergeben. Diese neue Version kann wiederum ein Trigger für eine weitere Pipeline sein.

Typische Concourse Resourcen sind ein Git Repository oder ein Registry Image. Ein typischer Ablauf mit diesen Concourse Resources sieht folgendermaßen aus: Bei der Git Resource wird ein neuer Commit als Trigger für das Starten einer Pipeline genutzt. Das Registry Image bekommt am Ende des Builds eine neue Version eines Docker Image. Das neue Docker Image ist eine neue Version der Registry Image Resource und kann somit als Trigger zum Starten einer anderen Pipeline genutzt werden. Es ist sehr einfach, neue Typen von Resources zu erstellen. Dazu muss ein Docker Image mit drei verschieden Skripten erstellt werden, die bestimmten Anforderungen genügen. Die Wahl der Programmiersprache ist dem Entwickler überlassen. Außer der Resource kennt Concourse noch Tasks und Jobs: Tasks beschreiben die Kommandos, die in der Pipeline ausgeführt werden. Sie laden dazu häufig neue Versionen von Resources herunter, erzeugen neue Artefakte und laden diese in eine andere Concourse-Ressource hoch. Jobs verbinden Tasks und Ressourcen: Wenn die Concourse Resource eine neue Version bekommt, triggert dies einen oder mehrere Tasks. Die geringe Anzahl an Bausteinen und die Entkopplung über Resources ermöglicht das Erstellen von sehr komplexen Pipelines.

Concourse kann seine Stärken vor allem bei großen Projekten ausspielen. Es bietet einige Features, die bei einem Vergleich mit anderen Systemen leicht übersehen werden. Es unterstützt eine Vielzahl von Methoden der Authentifizierung und eine Einbindung verschiedener Secrets-Management-Systeme wie zum Beispiel Vault. Es ist einfach, Concourse auf Kubernetes zu betreiben; Concourse macht allerdings keinen Gebrauch von Kubernetes-Funktionalitäten wie Pods oder Jobs, sondern startet lediglich das Web-UI und die Agents in Kubernetes. Die einzelnen Schritte werden durch die Agents zwar in Containern ausgeführt, allerdings nicht über das Kubernetes API. Obwohl Concourse Pipelines aus nur drei Komponenten bestehen, ist die Einarbeitung schwieriger als bei vielen Systemen der zweiten Generation.

Konsequent: Tekton CD

Tekton CD ist der neue Name von Knative Pipelines, ein Projekt, das Mitte letzten Jahres vorgestellt wurde. Ähnlich wie bei Concourse bestehen Pipelines bei Tekton CD aus drei Grundkomponenten: der Resource, dem Task und dem Step. Die Resource entspricht der Concourse Resource, der Task entspricht dem Job und was Concourse einen Task nennt, ist bei Tekton CD ein Step. Die einzelnen Komponenten werden bei Tekton CD ausschließlich mit Kubernetes-Konzepten implementiert. Fehlende Konzepte werden durch Erweiterung der Kubernetes API mithilfe von Custom-Resource-Definitions ergänzt.

Eine Pipeline besteht aus Resources und Tasks. Ein Task kann Teil einer Pipeline sein oder unabhängig ausgeführt werden. Resources können wie bei Concourse Eingaben (Git Repository) bereitstellen oder Build-Ausgaben entgegennehmen (Docker Image). Resources in Tekton können (noch) nicht als Trigger für Pipelines genutzt werden. Stattdessen muss manuell ein TaskRun oder PipelineRun erstellt werden. Tekton CD beobachtet die Erstellung neuer Run-Objekte und führt diese aus. Der Status eines Runs kann über die Kubernetes-typischen Werkzeuge auf der Kommandozeile mittels kubectl describe abgefragt werden.

Das Projekt ist vielversprechend, aber in einer frühen Phase. Zum jetzigen Zeitpunkt ist es noch notwendig, die Erstellung von TaskRuns und PipelineRuns selbst zu automatisieren. Des Weiteren verfügt Tekton CD über kein UI.

Der Spezialist: Prow

Prow ist eine Kubernetes-native Lösung, die erfolgreich für große Projekte wie Kubernetes, Istio und OpenShift genutzt wird. Das Triggern von Jobs erfolgt über GitHub Events wie Pre bzw. Post Commit Hooks. Eine weitere Möglichkeit, Aktionen bei Prow zu triggern, sind spezielle Kommentare in GitHub Pull Requests. Je nach Konfiguration ist es beispielsweise möglich, mit /test <project> Tests für ein Projekt zu starten. Diese Strategie ist an ChatOps angelehnt: Steuerung und Rückmeldungen des CI-Systems geschehen über eine Chatschnittstelle – in diesem Fall GitHub-Kommentare.

Ganz verzichtet Prow allerdings nicht auf eine grafische Benutzeroberfläche. Mit dem Prow-Dashboard können Nutzer einen Überblick der ausgeführten Jobs und deren Logs bekommen. Prow nutzt konsequent Kubernetes-Komponenten und erweitert die Kubernetes APIs, wie Tekton CD, wenn nötig durch Custom-Resource-Definitionen. Es wurde speziell für die Anforderungen und die Umgebung von Projekten der Cloud Native Computing Foundation entwickelt und nicht als generisches CI/CD-System. Das heißt unter anderem, dass es nur sinnvoll nutzbar ist, wenn Google Cloud Services genutzt werden und das Projekt auf GitHub gehostet wird. Andere Konfigurationen werden zur Zeit nicht unterstützt. Durch diese Fokussierung dürfte Prow für die meisten Set-ups keine akzeptable Lösung darstellen, auch wenn die Konzepte überzeugen und Prow beweist, dass es für den Produktiveinsatz bereit ist.

Des Kaisers neue Kleider: Jenkins X

Jenkins X ist eine Jenkins-Variante für Kubernetes. Das Herz von Jenkins X ist weiterhin Jenkins, das Cloudkomponenten steuert. Die Chance, einen sauberen Neustart zu wagen, wurde von der Jenkins-Community leider nicht wahrgenommen. Es ist schwer zu verstehen, was genau Jenkins X sein möchte. Sehr viele Komponenten, wie Prow, Knative, eine Docker-Registry, ein Helm-Chart-Repository und Nexus, werden automatisch mitinstalliert. Es folgt damit nicht dem Trend, kleine, fokussierte Komponenten zu erstellen. Im Vergleich mit anderen Systemen ist der Ressourcenhunger der Grundinstallation hoch. Allerdings zeichnet sich Jenkins X durch ein einfaches Aufsetzen aller Komponenten mit Hilfe des Kommandozeilentools jx aus. Es wird sogar die Provisionierung von Kubernetes-Clustern für Provider wie AWS, EKS, und GKE oder lokale Minikube-Installationen angeboten.

Jenkins X unterstützt weiterhin die Beschreibung der Pipelines mittels Jenkinsfile. Für GitHub-Code-Repositories definiert Jenkins X einen speziell angepassten Deployment-Prozess. In diesem Prozess werden Codeänderungen in Pull Requests zur Vorschau in eigene Namespaces deployt. Codeänderungen innerhalb eines Pull Requests werden automatisch neu deployt. Der URL der deployten App wird als Kommentar in dem Pull Request gepostet. Des Weiteren wird die Applikation automatisch in eine Staging-Umgebung deployt, sobald ein Pull Request in den Master-Branch integriert wird. Hierzu wird ein automatischer Pull Request in einem dedizierten Staging Repository geöffnet. Ein Staging Repository ist bei Jenkins X eine Sammlung von Helm-Charts für verschiedene Applikationen, die unter einem sogenannten Umbrella-Chart zusammengefasst werden. Mit Hilfe dieses Charts kann ein bestimmter Zustand in einem Kubernetes-Cluster erzeugt werden. Änderungen an diesem Repository werden automatisch mittels einer Jenkins Pipeline im Cluster angewendet.

Jenkins X nennt diesen Prozess des Deployens von Features in den nächsthöheren Stage Promotion. Die Promotion in der Produktivumgebung kann ausschließlich über das Kommandozeilentool jx ausgeführt werden, welches wiederum den Helm-Chart im Code-Repository für die Produktivumgebung aktualisiert. Damit werden Continuous-Deployment-Szenarien mit Jenkins X nicht ohne Weiteres unterstützt. Jenkins X ist ein eher untypischer Vertreter der dritten Generation. Zwar werden einige Kernfunktionalitäten von Kubernetes benutzt, allerdings läuft weiterhin ein voller Jenkins nebenher. Statt ein schlankes System mit Hilfe von Events aufzubauen, wird ein alter Allrounder mit noch mehr Möglichkeiten ausgestattet.

Zwischenfazit

Von den bisher vorgestellten Kubernetes-nativen CI/CD-Systemen kann noch keins bedenkenlos empfohlen werden. Grund sind mangelnde Reife oder eine Abhängigkeit auf externe Produkte wie zum Beispiel GitHub. Vermutlich ändert sich dieser Umstand in den kommenden Monaten, weshalb eine weitere Beobachtung dieser Systeme sinnvoll ist. Aktuell reicht das aber noch nicht aus, um an die einfache Service-Integration anzuknüpfen, die CI/CD-Systeme zweiter Generation bieten. Was also tun, wenn man aktuell ein CI/CD-System für Kubernetes nutzen möchte?

Zwischenlösung: GitLab CI/CD

GitLab CI/CD bietet neben der klassischen Agent-Lösung auch die Ausführung der GitLab Runners in Kubernetes an. Es spielt keine Rolle, ob GitLab selbst in dem betreffenden Kubernetes Cluster betrieben wird oder nicht. Die Installation des Runners erfolgt über ein einfaches Helm-Chart. Der Runner kann einer von mehreren GitLab CI/CD Runnern sein. Es ist so möglich, diesen ohne viel Aufwand zu testen.

Wird der GitLab Runner zusammen mit dem Kubernetes Executor betrieben, startet GitLab für jeden Schritt der Build Pipeline einen neuen Pod im Kubernetes Cluster. Es ist so möglich, die volle Kubernetes-Flexibilität zu nutzen, ohne auf ein ausgereiftes CI/CD-System zu verzichten (Abb. 3).

Abb. 3: Architektur mit GitLab CI Runner auf Kubernetes

Abb. 3: Architektur mit GitLab CI Runner auf Kubernetes

Da alle Pods in Kubernetes mit einem Service-Account gestartet werden, können – via Kubernetes Role-based Access Control – Deployments im selben Cluster einfach ermöglicht werden. Es ist dann nicht nötig, Zugriffsdaten zum Kubernetes Cluster in GitLab zu hinterlegen.

Auch GitLab CI/CD unterstützt sogenannte Review-Apps. Wird dieses Feature genutzt, werden Feature-Branches nach erfolgreichen Tests automatisch in ein eigenes Environment installiert. Ein Environment besteht aus einem dedizierten Namespace, eigenen Abhängigkeiten (zum Beispiel einer Datenbank) und einer Webadresse, unter der diese Version der App dann erreicht werden kann. Diese Webadresse kann Testern oder Kunden zur Verfügung gestellt werden. Wird der Feature-Branch in den Master-Branch gemergt, löscht GitLab den Namespace und damit alle Komponenten der App – inklusive der Webadresse.

Wer GitLab CI/CD und Kubernetes schon heute nutzt, sollte den Kubernetes Executor ausprobieren. Autoren von Pipelines müssen keinerlei Änderungen vornehmen und alte Runner nicht weiter betrieben werden.

Fazit

Seit CI/CD-Lösungen vor inzwischen fast zwanzig Jahren populär geworden sind, entwickeln sie sich kontinuierlich weiter, indem sie sich an die jeweiligen Bedürfnisse in Betrieb und Softwareentwicklung anpassen. Die enorme Popularität von Kubernetes hat zur Entstehung einer neuen Generation von CI/CD geführt. Diese muss noch reifen, hat aber ein hohes Potenzial.

Ein Hauptvorteil dieser Systeme ist ihre effiziente Ressourcennutzung. Kubernetes-native Systeme genießen immer den Vorteil dynamischer Skalierung ohne eigenen Konfigurationsaufwand. Gut gereifte Best Practices werden durch die neuen Systeme konsequenter angewendet:

  • Configuration as Code: Pipeline-Konfigurationen und Deployment-Definitionen werden in Code gegossen und sind somit versionierbar.
  • Pull-basiertes Deployment: Auf den Austausch von Zugangsdaten wie SSH Keys zur Ausführung von Deployments wird verzichtet; stattdessen werden Deployments auf der betreffenden Infrastruktur selbst ausgeführt.
  • Container-Zentrierung: Alle Schritte einer Build Pipeline werden in Containern ausgeführt. Hierbei werden ausschließlich die Werkzeuge und Berechtigungen benötigt, die für diesen speziellen Schritt erforderlich sind.

Die Architektur dieser neuen Systeme nutzt Strategien der Softwareentwicklung der letzten Jahre: Statt aus einem Monolithen, der jegliche Funktionalität implementiert, bestehen sie aus kleinen, entkoppelten Komponenten, die über Events miteinander kommunizieren. Das Cluster-Management wird nicht mehr im CI/CD-System implementiert, sondern von der genutzten Infrastruktur bereitgestellt.

Von den hier betrachteten Systemen sieht Tekton CD sehr vielversprechend aus, weil es gute Architekturentscheidungen von Concourse auf die Kubernetes-Plattform übertragen hat und gleichzeitig die Konfiguration einfach gestaltet.

Prow ist das einzige System der dritten Generation, das bereits intensiv in Produktion genutzt wird. Es könnte für die Allgemeinheit interessant werden, wenn sich eine Community findet, die das Projekt als unabhängiges Produkt weiterentwickelt.

Die Jenkins-Community kann trotz ihres großen Erfahrungsschatzes keine überzeugende Lösung liefern. Die Chance, den Jenkins-Monolithen durch kleine Komponenten zu ersetzen, wird nicht ergriffen. Stattdessen ist Jenkins jetzt Teil eines noch größeren Set-ups. Die beworbene Flexibilität, alte Jenkins-Komponenten noch nutzen zu können, kann schnell zum Nachteil werden.

Letztlich können Systeme der zweiten Generation wie GitLab CI/CD heute schon die Vorteile der dynamischen Skalierung von Kubernetes nutzen, ohne dass der Nutzer einen hohen Aufwand investieren muss. Sie eignen sich daher als gute Zwischenlösung, bis die Kubernetes-native Generation die notwendige Reife erreicht hat.

Geschrieben von
Daniel Bornkessel
Daniel Bornkessel
Daniel Bornkessel arbeitet als Senior Consultant bei der innoQ Deutschland GmbH. Seine inhaltlichen Schwerpunkte liegen auf den Themen DevOps, Automatisierung und Continuous Delivery.
Anja Kammer
Anja Kammer
Anja Kammer ist in der Softwareentwicklung und Administration von Cloud-native Applikationen tätig. Ein weiterer Schwerpunkt ist die Evaluation und Konfiguration von CI/CD-Systemen im Kubernetes-Kontext. Sie lehrte an der HTW Berlin Grundlagen der Informatik und hielt Workshops zu aktuellen Best Practices in der Softwareentwicklung. In der Vergangenheit war sie in der Asset-und-Property-Management-Branche tätig und automatisierte asynchrone Datenmigrationen und -aggregationen.
Jörg Müller
Jörg Müller
Jörg Müller ist Principal Consultant bei INNOQ. Seit mehr als zwanzig Jahren arbeitet er in verschiedenen Rollen in der IT-Beratung und Softwareentwicklung. In den letzten Jahren beschäftigt er sich schwerpunktmäßig mit der Architektur und dem Betrieb von Software as a Service. Aktuelle Themen sind Continuous Delivery, Microservices und Docker. In der Community ist er als Autor aktiv, hält Vorträge und ist beteiligt an der Organisation der JUG Berlin-Brandenburg sowie mehrerer Konferenzen.
Kommentare

Hinterlasse einen Kommentar

5 Kommentare auf "Kubernetes und seine CI/CD-Generationen"

avatar
4000
  Subscribe  
Benachrichtige mich zu:
gesellix
Gast

Drone CI ist noch erwähnenswert (stammt aus Generation 2, hat sich aber in Richtung Generation 3 entwickelt). Man kann zwischen self-hosted- und Cloud-Variante wählen: https://drone.io/

Clash
Gast

Eine mögliche Lösung für das Problem der Kopplung an GitHub bei Prow ist bspw. Lighthouse von Jenkins X: https://github.com/jenkins-x/lighthouse

Übrigens nutzt Jenins X auch Tekton Pipelines anstelle eines Classic Jenkins: https://jenkins-x.io/docs/concepts/jenkins-x-pipelines/

Clash
Gast

Interessant wären evtl. auch andere GitOps basierte Tools wie Weaveworks Flux https://www.weave.works/oss/flux/ oder ArgoCD https://argoproj.github.io/argo-cd/

HighTower
Gast

Ich kann bei der strikten Trennung nicht ganz mitgehen.
Insbesondere das reine Jenkins bietet mit Pipelines, Kubenetes-Support und stages/steps in Containern alle Merkmale von CI/CDs der dritten Generation.
So komme ich einen Build ohne BuildAgents, rein in K8s, nur durch ein Jenkinsfile beschrieben.

HighTower
Gast
GitLab als Docker Image is 750 MB groß. Jenkins als Docker Image gerade mal 300 MB. Jetzt verstehe ich nicht warum ausgerechnet Jenkins der böse Monolith sein soll und GitLab die Lösung. Mit folgendem Jenkinsfile ist eine Build-Pipeline beschrieben die Docker und K8s verwendet. Wo soll jetzt hier das Problem sein? pipeline { agent { kubernetes { yamlFile ‚BuildPods.yaml‘ } } stages { stage(‚My Build‘) { steps { container(‚mybuildimage‘) { sh ‚doit‘ } } } } }