CI/CD Überblick
Continuous Integration (CI) und Continuous Delivery (CD) sind wichtige Begriffe im Bereich DevOps. Sie umfassen Praktiken, die es modernen Entwicklungsteams ermöglichen, Codeänderungen häufiger und schneller zu liefern.
Dies wird durch Automatisierung beim Erstellen, Bereitstellen und Freigeben von Anwendungen erreicht.
CI sorgt dafür, dass Codeänderungen regelmäßig getestet und nach dem Zusammenführen in ein gemeinsames Repository (Versionskontrollsystem) freigegeben werden. Dadurch wird die Stabilität gewährleistet. CD ermöglicht die schnelle und reibungslose Bereitstellung dieser Änderungen, sodass sie in einer Live-Produktionsumgebung eingesetzt werden können.
CI und CD erleichtern die effiziente Veröffentlichung von Software. So können neue, hochwertige Produkte schneller als je zuvor auf den Markt gebracht werden.
Continuous Integration
Zuerst schauen wir uns das Konzept der Continuous Integration genauer an.
In der modernen Softwareentwicklung arbeiten Entwickler oft gleichzeitig an verschiedenen Funktionen.
Ohne kontinuierliche Integration kann es leicht passieren, dass beim Zusammenführen von Codeänderungen aus verschiedenen Branches Konflikte auftreten. Das nennt man dann ‘Merge-Conflict-Hölle’. Das passiert besonders häufig, wenn mehrere Feature Branches gleichzeitig zusammengeführt werden sollen.
- Erfahre mehr: Vor- und Nachteile verschiedener Git-Branching-Strategien.
Erster Schritt: Continuous Integration
Mit Continuous Integration (CI) können Developer ihre Codeänderungen hingegen in einen gemeinsamen Hauptzweig, den sogenannten Trunk, zusammenführen. Das nennt man trunk-basierte Entwicklung und ist ein wesentlicher Bestandteil von CI.
Dank dieser Methode können Entwickler ihre Änderungen in kleinen Schritten integrieren, oft sogar mehrmals am Tag. Jeder Commit löst dann einen automatisierten Build- und Testprozess aus.
Einfach gesagt, sobald diese Änderungen zusammengeführt sind, überprüfen automatisierte Tests den Build und erkennen eventuelle Fehler. So können Bugs schnell behoben werden, ohne dass die Software darunter leidet.
Vorteile der Continuous Integration
Da Developer häufig kleine Änderungen integrieren, wird eine schnellere Bereitstellung ermöglicht. Zudem gibt es schnelleres Feedback, sodass Developer Bugs nahezu sofort beheben können.
Bei trunk-basierter Entwicklung ist der Master Branch der einzige langfristige Branch, während alle anderen Branches nur eine begrenzte Lebensdauer haben.
Im Gegensatz dazu wird beim Feature Branching eine Kopie der Codebase erstellt, sodass Developer separat an ihren Features arbeiten können. Dies führt häufig zu Merge-Konflikten und im Extremfall zu Merge-Hölle, da Developer gleichzeitig zahlreiche Branches zusammenführen.
Da Developer in diesem Fall ihre Änderungen nicht häufig integrieren, erhalten sie kein schnelles Feedback. Sie können keine neuen Änderungen sehen oder ihre eigenen Features freigeben, bis alle Änderungen der anderen Developer fertig sind.
Anschließend versuchen sie, mehrere langfristige Branches zusammenzuführen, die möglicherweise erhebliche Änderungen (und somit größere Bugs) enthalten, die vermieden worden wären, wenn sie häufiger zum Trunk gemerged hätten.
Die Continuous Integration führt daher zu qualitativ hochwertigeren Releases, da Bugs schnell erkannt und behoben werden können. Dies führt zu erhöhter Effizienz und Produktivität, da Developer nicht länger darauf warten müssen, dass alle anderen ihre Änderungen abgeschlossen haben.
Erfahre mehr: Welche Branching-Strategien eignen sich am besten zur Unterstützung von Continuous-Integration- und Continuous-Delivery-Prozessen.
Nächster Schritt: Continuous Delivery
Continuous Delivery ist ein Ansatz zur Softwarefreigabe, bei dem Teams häufig qualitativ hochwertige Produkte durch eine Reihe automatisierter Tests veröffentlichen. Für einen effizienten Prozess der kontinuierlichen Bereitstellung muss auch die kontinuierliche Bereitstellung in deine Pipeline integriert werden. Mehr dazu später.
Das Ziel der Continuous Delivery ist es, Software zu haben, die immer bereit ist, aus dem Quell-Repository in eine Produktionsumgebung bereitgestellt zu werden. Mit anderen Worten, der Code ist immer in einem bereitstellbaren Zustand, selbst wenn mehrere Developer täglich Änderungen durch kontinuierliche Integration vornehmen. Obwohl dies meist ein automatisierter Prozess ist, kann die tatsächliche Freigabe in die Produktionsumgebung manuell durch das Team erfolgen.
Die Vorteile der Continuous Delivery sind klar
Schnellere Time to Market: Der offensichtlichste Vorteil ist die schnellere Markteinführung, da der Code immer bereit ist, an die Nutzer ausgeliefert zu werden.
Kontinuierliche Feedback-Schleife: Eine kontinuierliche Feedback-Schleife ermöglicht es Teams, kontinuierlich Feedback von ihren Endnutzern zu erhalten und dieses Feedback in die nächste Version zu integrieren.
Höhere Produktivität: Teams müssen sich nicht mehr mit langweiligen Aufgaben beschäftigen. Diese werden stattdessen von Pipelines erledigt. So können sich die Teams auf die Entwicklung besserer Produkte konzentrieren, was zu einer höheren Kundenzufriedenheit führt.
Risikoreduzierung: Wenn Änderungen häufiger in kleinen Schritten veröffentlicht werden, können Fehler leicht und schnell erkannt und behoben werden. Dadurch werden die typischen Risiken, die mit Releases verbunden sind, reduziert.
Continuous Integration vs. Continuous Delivery vs. Continuous Deployment
In der Softwareentwicklung beginnt der Prozess mit Continuous Integration. Continuous Delivery baut auf diesem Prozess auf, um die während der Continuous Integration in den gemeinsamen Trunk gemergten Änderungen freizugeben. Das bedeutet, dass Continuous Delivery die automatische Bereitstellung des Codes vom Entwicklungs- bis zum Produktionsstadium ermöglicht.
Daher stehen CI/CD für den kontinuierlichen Entwicklungs-, Test- und Bereitstellungsprozess neuer Releases.
Oft mit Continuous Delivery verwechselt, geht Continuous Deployment tatsächlich einen Schritt weiter.
In dieser Phase werden alle Änderungen automatisch und ohne menschliches Eingreifen veröffentlicht. Bei Continuous Delivery werden die Änderungen zwar für die Bereitstellung vorbereitet, aber der Zeitpunkt der Veröffentlichung wird manuell vom Team bestimmt.
Mit anderen Worten, Continuous Delivery ist ein teilweise manueller Prozess, während Continuous Deployment den gesamten Veröffentlichungsprozess automatisiert. Wenn ein automatisierter Test in dieser Phase fehlschlägt, wird die Änderung nicht veröffentlicht. Bestehen die Änderungen den Test, werden sie automatisch bereitgestellt.
Daher ist Continuous Deployment ein effizientes Mittel, um den Feedback Loop mit deinen Endnutzern zu beschleunigen.
Zusammengefasst die drei Hauptkonzepte:
- Continuous Integration
- Kurzlebige Branches, die mehrmals täglich in einen gemeinsamen Trunk gemergt werden. Eine Reihe automatisierter Tests gibt Feedback zu den eingeführten Änderungen.
- Continuous Delivery
- Nach der Continuous Integration bereitet Continuous Delivery die Software für die Bereitstellung vor; die Bereitstellung in die Produktion erfolgt meist manuell.
- Continuous Deployment
- Nach CI und CD werden Änderungen automatisch in die Produktion bereitgestellt; ein vollständig automatisierter Prozess.
Continuous Testing
Wir haben bereits erwähnt, dass Software während CI/CD eine Reihe automatisierter Tests durchläuft. Ein CI/CD-Prozess kann daher die folgenden Testarten umfassen:
- Unit Tests: Überprüfen einzelne Teile der Anwendung. Diese isolierten Teile der Code-Basis werden als Units bezeichnet.
- Integration Tests: Da Unit Tests sich auf einzelne Komponenten konzentrieren und möglicherweise allein nicht ausreichen, stellen Integration Tests sicher, dass mehrere Komponenten zusammen korrekt funktionieren und testen, wie Teile der Anwendung als Ganzes zusammenarbeiten.
- Functional Tests: Stellen sicher, dass die Funktion wie vorgesehen arbeitet.
- End-to-End Tests: Simulieren eine Benutzererfahrung, um sicherzustellen, dass echte Benutzer eine reibungslose, fehlerfreie Erfahrung haben.
- Acceptance Tests: Überprüfen das Verhalten der Software unter signifikanter Belastung, um ihre Stabilität und Zuverlässigkeit sicherzustellen.
Die folgende Testpyramide zeigt die verschiedenen Arten von Tests, die du durchführen kannst. In einigen Fällen musst du möglicherweise nicht alle diese Tests durchführen, insbesondere wenn du gerade erst anfängst.
Da Unit Tests am einfachsten zu implementieren sind und weniger Ressourcen benötigen, bilden sie in der Regel eine gute Grundlage für einen schnellen Build und ermöglichen Entwicklern schnelleres Feedback.
UI-Tests hingegen, die sicherstellen, dass eine Anwendung aus Benutzersicht korrekt funktioniert, sind viel langsamer und komplexer durchzuführen.
Zusammengefasst: Nicht jeder CI/CD-Prozess wird all diese Tests enthalten, aber es ist wichtig zu beachten, dass Continuous Testing durch Automatisierung ein wesentlicher Bestandteil von Continuous Integration und Continuous Delivery ist.
Was ist eine CI/CD-Pipeline?
Eine CI/CD-Pipeline ist eine Serie von automatisierten Tests, die Software durch ihren gesamten Lebenszyklus begleitet, indem sie den Quellcode bis zur Produktion bringt.
Eine typische Pipeline baut den Code, führt Tests durch und setzt die neue Software anschließend in einer originalgetreuen Nachbildung des Softwareentwicklungszyklus in die Produktion um.
Die Integration einer CI/CD-Pipeline ist ein wesentlicher Faktor für die Aufrechterhaltung einer DevOps-Kultur, da sie die schnelle und effiziente Veröffentlichung von Software mit minimalem Risiko gewährleistet. Der Aufbau einer CI/CD-Pipeline setzt die DevOps-Ideale in die Praxis um, indem sie Entwicklern ermöglicht, ihre Änderungen häufig zu committen und schnelles Feedback zu erhalten. Dies führt zu einer Kultur der Zusammenarbeit, erhöhter Produktivität und Transparenz innerhalb der Teams. Diese schnellen Feedback-Schleifen helfen, das Hauptziel einer effizienten CI/CD-Pipeline zu erfüllen: die Reduzierung des Risikos, das normalerweise mit neuen Releases verbunden ist.
Eine solche Pipeline umfasst die folgenden Elemente:
- Code bauen, mergen und testen – Continuous Integration
- Code für die Bereitstellung vorbereiten – Continuous Delivery
- Code automatisch bereitstellen – Continuous Deployment
Beispiel einer typischen CI/CD-Pipeline
Daher können wir die Phasen der CI/CD-Pipeline wie folgt zusammenfassen:
- Source: Die CI/CD-Pipeline wird ausgelöst, wenn neuer Code ins Repository committet wird.
- Build: Hier fügen Entwickler ihre neuen Codeänderungen ein und kompilieren sie, damit sie die erste Testphase durchlaufen können.
- Test: Der neue Code wird durch automatisierte Tests geprüft (zum Beispiel durch Unit Tests während der kontinuierlichen Integration). Je nach Größe und Komplexität der Software kann dieser Schritt von Sekunden bis Stunden dauern. Diese Phase liefert das notwendige Feedback, damit Entwickler eventuelle Probleme beheben können.
- Deploy: Der Code wird in eine Test- oder Staging-Umgebung bereitgestellt, um ihn auf die endgültige Freigabe vorzubereiten, also Continuous Delivery. Normalerweise wird der Build automatisch bereitgestellt, sobald er eine Reihe automatisierter Tests bestanden hat.
- Deploy to Production: Der Code wird in eine Live-Produktionsumgebung freigegeben, um die Endnutzer zu erreichen, entweder manuell oder automatisch.
Es ist wichtig, eine solche Pipeline in modernen Softwareentwicklungsteams zu haben, da diese Prozesse den Teams ermöglichen, ihre Energie und Zeit auf das Schreiben von Code und die Verbesserung von Produkten zu konzentrieren, während mühsamere Aufgaben automatisiert werden.
Dies entspricht der Idee einer echten DevOps-Kultur, bei der manuelle Prozesse durch Automatisierung reduziert werden. Ohne CI/CD würde das Integrieren, Testen und Bereitstellen von Änderungen separate Prozesse erfordern, die erheblichen Zeit- und Arbeitsaufwand bedeuten.
Solche automatisierten Prozesse sorgen daher für weniger Fehler und erhöhen die Zusammenarbeit und Effizienz im gesamten Softwareentwicklungszyklus.
Die Implementierung einer CI/CD-Pipeline fördert tatsächlich ein Umfeld der Zusammenarbeit, da Entwicklungs-, IT- und Betriebsteams zusammenarbeiten, um qualitativ hochwertigere Software häufiger bereitzustellen.
CI/CD: Best Practices
Zu den bewährten Methoden für eine effiziente CI/CD-Pipeline gehören unter anderem:
1. Änderungen früh und oft einpflegen
Denke daran, je öfter du Änderungen einpflegst, desto schneller erhältst du Feedback zu den Änderungen, die in den Trunk eingeführt wurden. Dies fördert die Zusammenarbeit und Produktivität im Team und reduziert das Risiko von Fehlern und Merge-Konflikten, wenn große Änderungen statt kleiner, häufiger Änderungen integriert werden.
Die allgemeine Regel lautet, mindestens einmal täglich Änderungen einzupflegen, damit alle im Team über die aktuellen Änderungen auf dem Laufenden bleiben. Selbst wenn die Features noch nicht vollständig sind, können unvollständige Änderungen mithilfe von Feature Flags vor dem Endnutzer verborgen werden. Mehr dazu später.
2. Mache es zur einzigen Möglichkeit, die Produktion bereitzustellen
Nachdem du eine zuverlässige und schnelle Pipeline aufgebaut hast, solltest du den Prozess nicht umgehen.
Mit anderen Worten, stelle sicher, dass alle eingeführten Änderungen durch die Pipeline gehen und dass dies der einzige Weg ist, um Code in die Produktionsumgebung zu bringen.
3. Überprüfe kontinuierlich deine Automatisierungsprozesse
In der modernen Softwareentwicklung entwickeln sich ständig neue Technologien und Prozesse. Daher ist es wichtig, kontinuierlich zu bewerten, welche Prozesse und Tests in deine Pipeline integriert werden können, um die Effizienz zu steigern.
Denke auch daran, dass nicht alles auf einmal automatisiert werden muss. Es ist manchmal besser, manuell zu starten, um zu überprüfen, was tatsächlich automatisiert werden muss.
4. Beschleunige deine Pipeline
Der Sinn einer CI/CD-Pipeline besteht darin, Dinge zu beschleunigen, um Software schneller als zuvor durch Automatisierung herauszubringen.
Eine allgemeine Faustregel ist, die schnellsten Tests zuerst auszuführen, bevor die Pipeline die anspruchsvolleren, zeitaufwändigeren Tests durchführt. Beispielsweise werden zuerst Unit-Tests, dann Integrationstests und anschließend Funktionstests ausgeführt. Auf diese Weise kannst du mit einfacheren, schnelleren Tests Fehler schnell erkennen und beheben, während die anspruchsvolleren Tests laufen.
Es geht also darum, zu wissen, wie die Tests in deiner Testsuite priorisiert werden.
5. Überwache deine Pipeline
Achte auch auf Verbesserungsmöglichkeiten, um zu verstehen, ob es Phasen in deiner Pipeline gibt, die optimiert werden müssen.
Überwache die von deinem CI/CD-Tool gesammelten Metriken, um Probleme zu identifizieren, die behoben werden müssen, um die Zuverlässigkeit und Leistung deiner Infrastruktur sicherzustellen.
CI/CD-Tools zur Gestaltung einer effizienten Pipeline
CI/CD kann Teams dabei helfen, die Prozesse der Entwicklung, des Testens und der Bereitstellung zu automatisieren. Einige Tools konzentrieren sich auf die kontinuierliche Integration, während andere eher auf die kontinuierliche Bereitstellung ausgerichtet sind.
In diesem Abschnitt stellen wir einige gängige Tools vor, die zur Automatisierung dieser Prozesse verwendet werden. Die Wahl der richtigen Tools ist entscheidend für die Implementierung einer effizienten CI/CD-Pipeline, die am besten zu deiner Organisation passt.
Beliebte Tools sind:
1. Jenkins
Eines der bekanntesten Open-Source-Tools für CI/CD. Als erweiterbarer Automatisierungsserver kann es als CI-Server verwendet und in ein Continuous-Delivery-Hub verwandelt werden.
2. CircleCI
Ein Tool, das flexible Umgebungen und tausende vorgefertigte Integrationen bietet. CI/CD-Orchestrierung in der Cloud oder die Möglichkeit, selbst gehostete Runner für zusätzliche Flexibilität und Kontrolle zu nutzen.
3. GitLab CI/CD
Dieses Tool ermöglicht es dir, deinen Release-Prozess zu optimieren und zu automatisieren, und bietet sichere und flexible Bereitstellungsoptionen. GitLab fungiert auch als die einzige Quelle der Wahrheit für CI/CD, sodass du deinen Code von einer einzigen Anwendung aus erstellen, testen, bereitstellen und überwachen kannst.
4. Travis CI
Eine Open-Source-CI/CD-Plattform, die Entwicklern hilft, Code schnell und einfach zu entwickeln, zu testen und bereitzustellen. Dieses Tool ist schnell einzurichten und unterstützt über 30 Sprachen, was große Flexibilität bietet.
5. Semaphore
Dieses Tool unterstützt eine Vielzahl von Sprachen und Plattformen, einschließlich iOS-Apps. Es kann verwendet werden, um deine Releases zu beschleunigen und über Web-, Desktop- und mobile Apps bereitzustellen.
6. Spinnaker
Eine Open-Source-Continuous-Delivery-Plattform, die mit einer Vielzahl von Cloud-Anbietern arbeitet, um schnelle, sichere und wiederholbare Bereitstellungen zu ermöglichen.
CI/CD + Feature Flags: Die magische Formel für noch schnellere Deployments
Wie wir gesehen haben, sind Continuous Integration und Continuous Delivery zwei wesentliche Praktiken, um qualitativ hochwertige Software schneller zu liefern.
Durch die Implementierung von Feature Flags in diese Prozesse wird zusätzlicher Wert geschaffen und das Risiko bei der Integration und Bereitstellung neuer Änderungen weiter reduziert.
Was sind Feature Flags?
Feature Flags sind ein Werkzeug in der Softwareentwicklung, mit dem bestimmte Funktionen ein- oder ausgeschaltet werden können, um sicher in der Produktion zu testen. Sie ermöglichen es, die Code-Bereitstellung von der Feature-Veröffentlichung zu entkoppeln.
Stellen wir uns folgendes Szenario vor: Mehrere Developer arbeiten an verschiedenen Änderungen über unterschiedliche Zeiträume hinweg. Was passiert, wenn einige Developer ihre Änderungen fertig haben, während andere noch nicht fertig sind? Früher bedeutete das, dass Developer warten mussten, bis alle im Team mit ihren Änderungen fertig waren, bevor sie diese schließlich integrieren und bereitstellen konnten.
Das führte oft zu unzufriedenen Kunden, die länger auf neue Releases warten mussten, und zu einer Unterbrechung des Feedback Loops, da Änderungen nicht häufig genug gemerged wurden. Mit Feature Flags können Developer ihre Änderungen pushen, ohne auf andere Developer warten zu müssen, indem sie einfach die unvollständigen Teile des Codes ausschalten.
Mit anderen Worten, diese unvollständigen Änderungen können hinter einem Feature Flag verborgen werden, während die fertigen Änderungen veröffentlicht werden. Sobald sie fertig sind, können sie eingeschaltet werden, um für Endnutzer sichtbar zu werden.
Das ist wichtig, da das Hauptziel der kontinuierlichen Integration darin besteht, Änderungen mindestens einmal täglich zu integrieren. Feature Flags helfen, dieses Tempo beizubehalten.Auf ähnliche Weise unterstützen Feature Flags die Continuous Integration.
Ebenso tragen Feature Flags dazu bei, das Versprechen Continuous Delivery einzulösen, denn Developer können weiterhin ein Release durchführen, während unvollständige Änderungen hinter einem Flag verborgen bleiben, sodass sie die Benutzererfahrung nicht beeinträchtigen.
Das bedeutet schnellere Markteinführungen und die Möglichkeit, kontinuierliches Feedback zu sammeln, um deine Produkte ständig zu verbessern und die Kundenzufriedenheit zu erhöhen.
Feature Flags sind auch als “Kill Switches” nützlich. Wenn ein Bug die automatisierten Tests passiert, kann er leicht ausgeschaltet oder zurückgerollt werden. Auf diese Weise wird nur die fehlerhafte Funktion deaktiviert und nicht das gesamte Release.
Das Hauptfazit ist, dass du mit Feature Flags Releases schneller und sicherer an Endnutzer liefern kannst.
Zusammenfassung
Zusammengefasst sind Continuous Integration und Continuous Delivery unverzichtbare Bestandteile der modernen Softwareentwicklung. Mit Feature Flags werden sie jedoch noch besser und leistungsfähiger, indem sie deiner CI/CD-Pipeline und letztlich deinen Kunden erheblichen Mehrwert bieten.