Geschwindigkeit ist alles, was Sie brauchen: kontinuierliche Lieferung geliefert

Share On

qlector

Bei Qlector sind wir bestrebt, hochwertige Software zu entwickeln und bereitzustellen und berücksichtigen dabei bewährte Engineering-Praktiken, wie sie in 12-Factor-Apps aufgeführt sind.

In dem folgenden Beitrag beschreiben wir, wie wir Continuous Delivery eingeführt haben. Dadurch reduzieren wir Verschwendung, Entwicklungskosten und steigern die Qualität. Zuerst werden wir die Praxis und Prinzipien kurz beschreiben und danach im Detail darauf eingehen, wie wir sie bei Qlector implementiert haben. Im Laufe des Beitrags verweisen wir auf relevante Beiträge, die für uns nützlich waren, als wir über Probleme nachdachten und eine Pipeline entwarfen.

Definitionen, Prinzipien und Metriken

CI & CD: Wie definieren wir sie?

Die drei Praktiken sind miteinander verbunden und stehen für höhere Stufen der Build-Automatisierung. Continuous Integration ist die Praxis, bei jedem Commit auf einem unabhängigen Server Builds und Tests auszuführen. Dieser Server sollte eine saubere Umgebung garantieren, in der der Code von Grund auf neu erstellt wird, um sicherzustellen, dass keine Fehler auftreten oder Tests aufgrund eines inkonsistenten Zustands fehlschlagen. Möglicherweise müssen wir den Code auch in verschiedenen Umgebungen erstellen, um sicherzustellen, dass derselbe Code nicht unterschiedlich reagiert, abhängig von der Umgebung.

Continuous Delivery geht noch weiter: Für jeden Commit erstellen wir ein Binärpaket, das mit einem Knopfdruck in der Produktion bereitgestellt werden kann, wodurch diese Entscheidung zu einer Geschäftsentscheidung wird. Continuous Deployment bedeutet, das Binärpaket aus jedem Commit bereitzustellen – ohne menschliches Eingreifen.

Nicht jedes Softwareprojekt kann Continuous Deployment in die PROD-Umgebung einführen, aber die Einführung in andere Stufen hilft erheblich dabei, Bereitstellungen besser zu verstehen und sie weniger problemanfällig zu machen, die Rückmeldungsschleife zu verkürzen und Zeit in Aufgaben zu investieren, die automatisiert werden können. Durch häufiges Ausführen dieser Aufgaben in einer risikofreien Umgebung setzen wir den Bereitstellungs- und Implementierungsprozess unter konstanten Druck, reduzieren somit seine Fragilität und wandeln ihn in eine risikoarme Aktivität in der Produktion um.

Prinzipien

Continuous Delivery is based on 5 principles:

  • Continuous Delivery basiert auf 5 Prinzipien:
  • Qualität in den Build einbauen: Je später wir Fehler finden, desto höher sind die Kosten. Wir streben einen kurzen Rückkopplungszyklus an, um Probleme so schnell wie möglich zu erkennen und zu beheben.
  • In kleinen Chargen arbeiten: Dies ermöglicht schnellere Rückmeldungen und eine geringere Oberfläche zur Erkundung im Falle von Problemen, wodurch wir kurz nach der Erkennung Lösungen finden können.
  • Computer führen repetitive Aufgaben aus, Menschen lösen Probleme: Menschen sollten ihre Zeit in kreative Aktivitäten investieren und dort automatisieren, wo es möglich ist, um auch wirklich Zeit dafür zu haben. Dies erhöht nicht nur die Prozessqualität (weniger menschliche Fehler im Laufe der Zeit), sondern motiviert auch die Mitarbeiter, da sie sich sinnvoller Arbeit widmen können.
  • Kontinuierliche Verbesserung unerbittlich verfolgen: Continuous Delivery ist kein einmaliges Ereignis, sondern eine Einstellung: Wir können den Prozess immer verbessern und dadurch die Gesamtqualität und Produktivität steigern.
  • Jeder ist verantwortlich: Das Ziel ist es, ein besseres Produkt zu schaffen, und das erfordert Teamarbeit. Bessere Qualität und Lieferung ist keine Angelegenheit isolierter Teams, sondern betrifft jeden einzelnen im Unternehmen.
  • Für weitere Details zu Mustern und Prinzipien empfehlen wir continuousdelivery.com sowie zwei relevante Bücher zu dieser Praxis: Continuous Delivery und Accelerate.
  • kontinuierliche Lieferung Produktionsplanung Terminierung

continuous delivery production planning scheduling

Wie misst man Continuous Delivery?

In jedem Unternehmen und bei jeder Initiative benötigen wir Metriken für den Erfolg – einige KPIs, die es uns ermöglichen, unsere Leistung zu verstehen. Wie messen wir Continuous Delivery? Der State of DevOps-Bericht und das Buch Accelerate heben hervor, dass wir zur Vorhersage und Verbesserung der Leistung eines Teams nur vier Schlüsselkennzahlen messen müssen: Durchlaufzeit, Bereitstellungsfrequenz, mittlere Wiederherstellungszeit (MTTR) und Änderungsfehlerrate. Diese Metriken wurden auch von dem neuesten ThoughtWorks Technology Radar als lohnenswert herausgestellt.

Entwurf der Pipeline

Als wir uns verpflichteten, eine Continuous-Delivery-Pipeline aufzubauen, suchten wir nach Prinzipien, um sie auf einer soliden Grundlage zu entwerfen und zu erstellen. Diese Prinzipien sind: Pakete einmal erstellen, überall auf die gleiche Weise bereitstellen, Bereitstellungen mit Smoke-Tests überprüfen und Umgebungen ähnlich halten.

Unveränderlichkeit hat viele Vorteile, und deshalb haben wir darauf in verschiedenen Phasen geachtet:

  • Wir verwenden Docker, um Build-Slaves bei Bedarf bereitzustellen: Diese werden für einen einzelnen Build erstellt und zerstört, wenn sie fertig sind, um eine saubere Umgebung zu gewährleisten. Um sicherzustellen, dass die richtigen Slaves erstellt werden, kennzeichnen wir Slave-Typen und ordnen ihnen bestimmte Docker-Images zu, um die Umgebung zu kontrollieren, in der Builds ausgeführt werden.
  • Um sicherzustellen, dass Binärdateien einmal gebaut, zugänglich und unveränderlich bleiben, verwenden wir ein Tool zur Verwaltung von Binärdateirepositorien. Unsere Wahl fiel auf JFrog Artifactory.
  • Von der Unveränderlichkeit der Binärdateien bis zur Umgebung, in der die Anwendung ausgeführt wird, ist es ein langer Weg. Wir verwenden Docker, um dies zu erreichen: Für jeden Build rufen wir die neueste Binärdatei ab, installieren sie auf einem Docker-Image und veröffentlichen sie. Auf diese Weise können wir überall jede Version starten, was es einfach macht, die neueste Version bereitzustellen, bei Bedarf zurückzukehren, wenn ein Problem gefunden wurde, oder eine bestimmte Version mit derselben Umgebung zu reproduzieren.
  • Jenkins enthält viele Informationen. Im letzten Jahr wurde ein großartiges neues Feature entwickelt, das es uns ermöglicht, Jenkins Configuration as Code (JCasC) zu spezifizieren. Wir haben es ausprobiert und alle unsere Plugins und Pipelines mit dieser Funktion codiert. Obwohl es noch nicht ausgereift ist, finden wir es sehr vielversprechend und sind der Meinung, dass es der richtige Weg ist.
  • Pipeline-Produktionsplanung Terminierung

pipeline production planning scheduling

Wie sieht unsere Pipeline aus?

  • Immer wenn ein Commit auf Github gepusht wird, startet Jenkins einen Build für dieses Projekt. Ein neuer Slave wird mit der richtigen Umgebung erstellt, der Code wird aus dem Repository unter Verwendung von Github Deploy Keys abgerufen und gebaut, und Tests werden ausgeführt.
  • Wenn alle Tests erfolgreich abgeschlossen sind, wird eine Binärdatei erstellt und in JFrog Artifactory hochgeladen, und unser Slave wird beendet.
  • Ein anderer Slave wird das neueste Build aus unserem Binärdateirepositorium abrufen und auf einem vordefinierten Docker-Image installieren, um eine neue Version auf Docker Hub freizugeben. Jedes neue Image wird mit zwei Tags versehen: der entsprechenden Version und „latest“, um sicherzustellen, dass wir immer die neueste Version abrufen können.
  • Schließlich geben wir die entsprechenden Benachrichtigungen über Erfolg oder Misserfolg aus. Hier haben wir verschiedene Richtlinien, wie der Build-Status kommuniziert wird. Wir benachrichtigen normalerweise nur, wenn sich der Status ändert, um eine Überlastung mit Benachrichtigungen (und die daraus resultierende Aufmerksamkeitsminderung der Empfänger) zu vermeiden. Benachrichtigungen werden in einen Slack-Kanal ausgegeben, den alle abonniert haben.


Als Standardpraxis werden wichtige Zeitstatistiken pro Pipelinestufe und ihr Status von der Jenkins Build Pipeline angezeigt, und der aktuelle Status der Pipelines kann auf unserem Jenkins Build Monitor visualisiert werden.

Geschichten über den schwierigen Aufbau der Pipeline

Die Dinge sind leichter gesagt als getan 🙂 Aber wir erinnern uns alle stolz an schwierige Zeiten, die es uns ermöglicht haben, Erfindungsreichtum und Hartnäckigkeit bei der Lösung der dringendsten Probleme zu zeigen. Der Aufbau der Pipeline war keine Ausnahme, und wir möchten unsere Erfahrungen mit einigen Problemen teilen, mit denen wir bei der Entwicklung konfrontiert waren.

Bereitstellung von Slaves mit Docker

Wir verwenden das Docker-Plugin zur Bereitstellung von Slaves. Einige Probleme, mit denen wir anfangs konfrontiert waren, bestanden darin, wie wir den Docker-Host für Jenkins zugänglich machen und den Slave dann ordnungsgemäß konfigurieren, um eine Schnittstelle zum Master zu schaffen. Wir haben uns entschieden, über SSH zu kommunizieren und die Jenkins Docker SSH-Slave-Vorlage entsprechend anzupassen. Eine bewährte Methode besteht nicht nur darin, eine eindeutige Instanz pro Build zu haben, sondern auch ein neues Schlüsselpaar auszugeben, um sich bei jedem der Slaves anzumelden, sodass niemand außer dem Master sich bei ihnen anmelden kann. Wir haben dies erreicht, indem wir beim Konfigurieren der Docker-Agentenvorlagen eine SSH-Schlüssel-Injektion angefordert haben.

Docker-in-Docker (DinD)-Konfiguration

Wir haben eine DinD-Konfiguration in Betracht gezogen, uns aber schließlich entschieden, den Jenkins-Master auf einem dedizierten Server auszuführen und nur seine Slaves zu dockerisieren (mit Ausnahme derjenigen, die Docker-Images erstellen). Dieser Beitrag enthält eine tolle Zusammenfassung potenzieller Probleme sowie Links zu weiteren relevanten Ressourcen.


Unsere endgültige Architektur führt Code-Building und Tests bis zur binären Veröffentlichung im Binär-Repository-Management innerhalb von Docker-Slaves durch. Dann wird die Binärdatei auf einem nicht-dockerisierten Slave abgerufen und das Docker-Image erstellt und veröffentlicht.

Smoke Testing des Images

Nachdem wir unsere Docker-Images erstellt haben, stellen wir sicher, dass die Anwendung mit den zugehörigen Diensten wie erwartet startet. Erst nachdem diese Überprüfungen erfolgreich abgeschlossen sind, pushen wir sie in das Docker-Repository und gewährleisten damit ein neues Qualitätsniveau. Die von uns erstellten Images werden vom lokalen Slave entfernt, um unnötige Speicherplatzverschwendung auf der Festplatte zu vermeiden.

Build notifications: implementation and policies

Benachrichtigungen sind ein zentrales Feature der Pipeline: Die richtige Nachricht und Konfiguration können durchaus über ihren Erfolg entscheiden. Die Verkürzung der Rückkopplungsschleife bedeutet, dass klar kommuniziert wird, wofür die Pipeline gebaut wurde: ob die von uns eingeführten Änderungen gut sind oder etwas behoben werden muss.

Wir haben uns entschieden, den Status der Builds über Slack zu kommunizieren. Gemäß unserer Erfahrung kann eine Benachrichtigung für jeden Build zu vielen irrelevanten Status führen, die die Aufmerksamkeit der Entwickler aufgrund einer Überlastung mit Benachrichtigungen verringern. Eine alternative Methode wäre, nur bei fehlerhaften Builds oder bei Statusänderungen zu benachrichtigen – Richtlinien, die wir implementiert haben. Wir danken Betterment, die ihre Erfahrungen zu diesem Thema geteilt haben, und haben uns entschieden, einen Code-Snippet mit Richtlinien und Nachrichtenformatierung sowie verschiedene Emojis für jeden Build-Status bereitzustellen, damit die Nachrichten nicht immer gleich sind. 🙂

jenkins production planning scheduling

Integration von Kontext in Docker-Image-Profile

Unter den Continuous-Delivery-Pipeline-Mustern finden wir das Muster des einmaligen Erstellens von Paketen: Indem wir denselben Code bereitstellen, den wir getestet haben, eliminieren wir Pakete als Fehlerquelle. Da wir Container aus demselben Image in verschiedenen Kontexten bereitstellen müssen und jeder Kontext seine eigenen Konfigurationen hat, haben wir Support für Profile eingebaut: Abhängig von ihnen können wir verschiedene Konfigurationen laden und sicherstellen, dass sich derselbe Build je nach Kontext unterschiedlich verhält.

Wie verfolgen wir Änderungen über die gesamte Pipeline hinweg? Versionierung könnte uns helfen…

Wie handhaben wir die Versionierung?

Ein wichtiger Aspekt der Softwareentwicklung ist die Versionierung, die dazu dient, Änderungen in den von uns bereitgestellten Binärdateien zu kommunizieren. Die Versionierung kann eine große Herausforderung sein, da sie sinnvolle Informationen für Menschen vermitteln muss, aber wir sollten ihre Erstellung an Maschinen delegieren können. Wie sind wir dieses Problem bei Qlector angegangen?

Die Versionierung kann im Allgemeinen genutzt werden, um Informationen über Folgendes zu vermitteln:

  • die Tragweite der Änderungen,
  • ob der Build eine endgültige Version oder eine Version in Bearbeitung ist,
  • Nachverfolgung des neuesten Commits, sodass wir schnell eine Binärdatei mit ihrem entsprechenden Status im Codebestand verknüpfen können.
  • Indem wir eine deterministische Heuristik bereitstellen, stellen wir sicher, dass unter denselben Umständen dieselbe Version erstellt wird.

Tragweite der Änderungen

Wenn wir über die Tragweite der Änderungen sprechen, meinen wir, ob die Änderungen, die wir in eine neue Version einführen, mit der vorherigen API kompatibel sind, neue Funktionen hinzufügen und/oder gemeldete Probleme beheben. Diese Informationen werden am besten gemäß der SemVer-Konvention vermittelt, die aufgrund ihrer Klarheit zum Standard geworden ist. SemVer unterstützt auch das Hinzufügen von Vorabversionen und Commit-Tags-Funktionen, die wir verwendet haben, um zusätzliche aussagekräftige Informationen zu vermitteln.

Endgültige vs. WIP-Versionen

Es wäre schön, nur anhand einer Version zu erkennen, ob sie einem endgültigen Release (Meilenstein) entspricht oder einem Work-in-Progress. Zu diesem Zweck haben wir das Konzept des SNAPSHOT-Release von Maven übernommen. Zusätzlich zur SemVer-Nummer fügen wir WIP-Releases das SNAPSHOT-Tag hinzu.

Verfolgung des Builds zurück zu einem Git-Commit

Ähnlich wie beim SNAPSHOT-Tag können wir auch einen kurzen Git-Commit-Tag hinzufügen: Auf diese Weise können wir jede Build-Version bis zum Commit zurückverfolgen, der sie generiert hat. Auf diese Weise haben wir eine Referenz zur Priorisierung von Problemen im Codebestand, wenn sie aus einer bereitgestellten Umgebung gemeldet werden.

versioning production planning scheduling

Automatische Versionierung

Wenn wir eine Pipeline entwickeln, müssen wir einen Mechanismus zur Automatisierung der Versionierung bereitstellen: etwas, das die oben genannten Regeln berücksichtigt und eine geeignete Version für das nächste Release bereitstellt. Zu diesem Zweck haben wir ein Skript erstellt, das eine Version vorschlägt, die auf dem letzten Git-Tag-Versionshash und dem letzten Commit-Hash basiert:

  • wenn der letzte Commit mit dem getaggten übereinstimmt, geben wir den Tag als Version zurück’
  • wenn der letzte Commit nicht mit dem letzten getaggten übereinstimmt,
  • erhöhen wir den Minor-Wert der Version, die wir aus dem Git-Tag erhalten haben, um eins
  • fügen wir das SHAPSHOT-Tag hinzu
  • In allen Fällen fügen wir die Kurzversion des aktuellen Commit-Tags hinzu, um die Rückverfolgbarkeit zwischen der Build-Version und dem Codeversionierungssystem zu gewährleisten.

Wir möchten uns bei Code54 für ihre Gedanken zur Versionierung bedanken, die sie mit dem Build-Version-Plugin geteilt haben, und deren Ansatz wir bei der Entwicklung unseres eigenen gefolgt sind.

Schneller ist besser: Beschleunigung der Feedbackschleife

Bei Qlector legen wir großen Wert auf Agilität: Je kürzer die Feedbackschleife, desto schneller entwickeln wir Funktionen, identifizieren wir Probleme und beheben sie.

Nachdem wir unsere Continuous-Delivery-Pipeline eingerichtet hatten, sahen wir zwei Möglichkeiten zur Beschleunigung:

  • kontinuierliches Deployment in risikofreien Umgebungen und Erlernen von Best Practices, damit die Produktion reibungslos verläuft
  • Optimierung unserer Entwicklungsumgebung, sodass lokale Versionen von Diensten erstellt und Mittel bereitgestellt werden, um Feedback zu neuem Code zu erhalten


Mit Entwicklungsabhängigkeiten auf dem Laufenden bleiben

Die Aktualität der Abhängigkeitsversionen ist aus Sicherheitsgründen wichtig (Vermeidung von Schwachstellen) und um die Upgrade-Lücke zu minimieren (je größer die Verzögerung, desto größer die Lücke der Änderungen, die wir in unserem Code anpassen müssen – inkrementelle Änderungen vermeiden große Refactorings). Trotzdem führen nicht alle Teams und Projekte regelmäßig Aktualisierungen durch. Untersuchungen zu diesem Thema haben ergeben, dass einige Praktiken den Teams dabei helfen können, Abhängigkeiten regelmäßig zu aktualisieren.

In unserem Fall haben wir uns entschieden, keine automatisierte PR für Versionsänderungen einzuführen, sondern einen regelmäßige Job zu haben, der Aktualisierungen testet und uns benachrichtigt, wenn unser Code ohne Probleme gebaut wird.

Auf dem Weg zu einer agilen Entwicklungsumgebung

Selbst mit einer kontinuierlichen Bereitstellungs- oder Deployment-Pipeline verbringen wir die meiste Zeit mit der Programmierung in einer lokalen Umgebung, und alles, was wir tun, um diesen Prozess zu beschleunigen, wird wahrscheinlich einen großen Einfluss auf die Produktivität haben.

Einer der Grundsätze der kontinuierlichen Bereitstellung ist es, die Unterschiede zwischen den Umgebungen so gering wie möglich zu halten. Dies gilt auch für die Entwicklung. Aus diesem Grund haben wir beschlossen, ein Image zu erstellen, das mit der Produktionsumgebung identisch ist und das den Code aus dem Repository einbindet, die erforderlichen Abhängigkeiten installiert und auf Codeänderungen achtet. Bei Codeänderungen werden die Quellen neu kompiliert, Tests durchgeführt und sofortiges Feedback gegeben, wenn sich etwas nicht wie erwartet verhält.

Nachdem wir auf dieses Schema umgestellt hatten, konnten wir auch die Zeit für die Einrichtung der Umgebung für Neulinge verkürzen: mit zwei Befehlen war alles eingerichtet. Außerdem konnten wir so sicherstellen, dass die Dinge in der Produktion wie erwartet funktionieren und dass in der lokalen Umgebung nichts aufgrund von Code- oder Konfigurationsresten fehlschlägt.

Wir fanden viele Verbesserungsmöglichkeiten, setzten Standardverfahren wie kontinuierliche Kompilierung und Tests durch und arbeiteten auf ein schlankes Setup hin. Auf diese Weise konnten wir die Einrichtungszeiten erheblich verkürzen und erhielten schnelleres Feedback zu neu entwickeltem Code.

Noch ein Schritt weiter: Dockerisierte Entwicklungsumgebungen!

Continuous Delivery folgt einigen Grundsätzen, die dem Lean-Prinzip inhärent sind: kontinuierliche Verbesserung durch die Beseitigung aller Arten von Verschwendung – in unserem Fall durch die Automatisierung sich wiederholender Aufgaben und die Konzentration auf Aufgaben, die zur Wertschöpfung beitragen – also solche, die menschliche Kreativität und Fähigkeiten erfordern. Können wir eine Entwicklungsumgebung aufbauen, um dies zu erreichen?

platform production planning scheduling

Indem wir diesem Lean-Prinzip folgen, haben wir Funktionen identifiziert, die eine solche Plattform erfüllen sollte:

  • Die Umgebung sollte den Entwicklern keine Einschränkungen auferlegen: Jeder sollte in der Lage sein, mit dem Betriebssystem und der IDE seiner Wahl zu arbeiten, um unnötige Lernkurven zu vermeiden.
  • Wir sollten dieselbe Umgebung wie in der Produktion replizieren, um sicherzustellen, dass neben denjenigen, die unter gleichen Bedingungen auftreten können, keine anderen Probleme auftreten. Dadurch standardisieren wir das Betriebssystem, Abhängigkeiten (bei Betriebssystem- und Anwendungspaketen), Komponentenstandorte, Codierungen sowie Benutzer und Berechtigungen.
  • Wir sollten Probleme aufgrund veralteter Bedingungen auf Entwicklerseite verhindern, wie veraltete Pakete, Konfigurationen oder Dateien. Manchmal funktionieren Dinge lokal, sind aber auf anderen Maschinen nicht reproduzierbar.
  • Konfigurierbar machen: Der Entwickler kann entscheiden, ob alle oder nur einige Module und Dienste ausgeführt werden sollen und wie: Wie üblich, indem Änderungen überwacht und neu kompiliert, gelintet und / oder der Code bei Änderungen getestet wird? Sollen wir beim Start der Umgebung dort weitermachen, wo wir aufgehört haben, oder: die Datenbank neu erstellen? Den Container neu erstellen?
  • Bereitstellung von Konfigurationen, Zertifikaten und Standardanmeldeinformationen, damit sich der Entwickler keine Gedanken darüber machen muss, bis eine bestimmte Änderung erforderlich ist.
  • Bereitstellung von Tools und Mitteln zur Erleichterung der Fehlersuche.

Wir haben dies erreicht, indem wir eine Docker-Image-Hierarchie verwendet haben, die uns dieselbe Umgebung für Entwicklung, CI sowie Produktion bietet und es uns ermöglicht, alle Dienste gemäß der Docker-Compose-Definition zu starten. In der Entwicklung spiegeln wir den Code aus dem Git-Repository in den Container und führen die Module darin aus, während das Produktionsimage aus demselben Basisimage erstellt wird, aber die veröffentlichten Binärdateien darin persistiert werden. Um Fehlanpassungen in den Docker-Compose-Definitionen zu vermeiden, stellen wir eine Basisdefinition und modulare Überschreibungen bereit, die spezifische Änderungen in DEV oder PROD verfolgen. Diese Definitionen werden bei jedem Start neu generiert, um sicherzustellen, dass wir nie auf einer veralteten Konfiguration laufen. Wir verhindern veraltete Bedingungen auf Containern, indem wir Mittel bereitstellen, um Container sowie zugehörige Volumes bei Bedarf neu zu erstellen. Die Abhängigkeiten der Entwickleranwendung werden nicht in Docker-Images persistiert, sondern durch Angabe der erforderlichen Versionsnummer gesperrt. Die Entwicklungsumgebung wird heruntergeladene Abhängigkeiten zwischenspeichern, um deren erneuten Download zu verhindern und schnelle Starts zu gewährleisten.

Einstellungen für die Entwicklerumgebung (welche Module ausgeführt werden sollen und ob Code-Änderungen überwacht werden sollen) sowie Anmeldeinformationen und SSL-Zertifikate werden standardmäßig generiert, können aber jederzeit von Entwicklern überschrieben werden.

Beim Überwachen von Änderungen stellen wir sicher, dass die erforderlichen Module kontinuierlich kompiliert werden und der Entwickler über die Konfiguration zusätzliche Überprüfungen anfordern kann (Testen und/oder Überprüfen des Codes).

Die Fehlersuche ist eine der wichtigsten Aufgaben bei der Entwicklung. Wenn man Zeit investiert, um sie zu erleichtern, Sichtbarkeit zu gewinnen oder einfach den Weg zu relevanten Verzeichnissen zu verkürzen, spart dies Entwicklern Zeit.

Um den Zugriff auf die Konsole zu ermöglichen, haben wir zwei Befehle hinzugefügt, mit denen wir uns in Container einloggen und tmux-Sitzungen mit vordefinierten Fensterlayouts über alle laufenden Prozesse und Datenbanken anhängen können. Die Panels sind basierend auf interagierenden Komponenten gruppiert, damit wir uns auf einen bestimmten Bildschirm konzentrieren können, um das Verhalten zu beobachten, Probleme zu diagnostizieren und an einer Lösung zu arbeiten.

Da die Fehlersuche manchmal einen separaten Satz von Tools erfordert, die nicht Teil der laufenden Anwendungen sind, haben wir einen spezifischen Container entwickelt, der sich an die laufende Umgebung anbindet und Hilfsskripte bereitstellt, die bei der Aufgabe helfen können. Die Skripte, die wir entwickeln, um eine bestimmte Situation besser oder schneller zu diagnostizieren, sind in diesem Docker-Image enthalten, um die Teamproduktivität zu steigern.

Fehler können in jedem Schritt des Stacks auftreten, und es ist wichtig, über alle Stufen hinweg Transparenz zu haben. Wenn eine Anfrage fehlschlägt, sollten wir wissen, ob dies auf falsche Nginx-Zuordnungen zurückzuführen ist oder ob ein Dienst aus irgendeinem Grund nicht antwortet. Unsere Konfiguration bietet die Möglichkeit, Anfragen durch den gesamten Stack zu senden oder an jeder Stelle einzusteigen, um das Problem zu diagnostizieren.

Am Ende der Pipeline gibt es Licht!

Die Implementierung einer Continuous-Delivery-Pipeline war eine großartige Reise, die noch andauert, während wir daran arbeiten, unsere Pipeline bis hin zu den Bereitstellungen zu verbessern. Einige Vorteile, die wir daraus gezogen haben, sind eine schnelle Rückkopplung während der Produktentwicklung, vereinfachte Konfigurationen über mehrere Umgebungen hinweg, kurze Einrichtungszeiten, messbare Qualität und umsetzbare Elemente aus Berichten sowie dockerisierte Bilder, die in jeder Umgebung funktionieren – veröffentlicht für jeden funktionierenden Commit, den wir pushen. Auch wenn es anfangs vielleicht ein wenig beängstigend erscheint, erweist sich das Prinzip der kleinen Chargen als hilfreich, um schneller und besser zu entwickeln.

Hatten Sie ähnliche Erfahrungen oder richten Sie gerade Ihre Pipeline ein? Kontaktieren Sie uns – wir würden gerne von Ihren Erfahrungen hören! Denken Sie über einen neuen Job nach? Wir suchen immer nach den besten Fachleuten!

Read more articles

Bereichern Sie Ihr SAP mit QLECTOR LEAP

KI in der Fertigung: Neueste Trends zeigen eine Verschiebung vom Effizienzsteigerungsimperativ hin zu Flexibilität und Resilienz

„Bei der Digitalisierung geht es nicht um technische Schlagwörter, sondern darum, Probleme zu lösen.“