Schlagwort-Archive: cicd

Dockerimage für CI/CD mit Sloppy CLI

In CI/CD-Situationen, also in Situationen, in denen wir automatisiert gewisse Aussagen über und Aufgaben am aktuellen Entwicklungsstand einer Software vornehmen wollen, sind wir häufig auf die Kommandozeile angewiesen.

TL;DR: Das Runner-Image z.B. für GitLab ist auf DockerHub frei verfügbar dielok/sloppy-cicd. Wir werden die Dockerfile auch in Kürze bei Github veröffentlichen.

Über entsprechende Skripte, also aneinandergereihte Befehle, automatisieren wir dann den Prozess und visualisieren ihn in Form von sogenannten Build- und Deploymentpipelines.

Auch mit dem Cloud-Anbieter Sloppy muss dies natürlich irgendwie innerhalb eines Skriptes möglich sein, damit wir den Entwicklungsstand auch automatisiert veröffentlichen können. So kann die Anwendung auch letztlich von Endnutzern verwendet werden. Dies kann ein Server sein, oder ein ganzes Netzwerk aus Servern, daher sprechen wir von Umgebungen. Auf der sogenannten Produktivumgebung läuft die Anwendung für den Endverbraucher. Umgangssprachlich „Prod“.

Auch auf Umgebungen die nicht produktiv sind, müssen die aktuellen Entwicklungsstände ausgerollt werden können. Diese dienen beispielsweise den Tests der Qualitätssicherung, Demonstrationen für Stakeholder und der Beobachtung des Fortschritts durch Manager. Das soll so zuverlässig, einfach und schnell wie möglich ablaufen: Also automatisiert.

Das geht mit Sloppy im Handumdrehen. Super einfach ist ein neues Projekt (Umgebung) angelegt, Services, Apps in Form von Docker-Containern definiert.Nicht nur in dem UI. dem Portal von Sloppy. Sloppy bietet eine gut entwickelte CLI-Anwendung, mit der Apps, Services und Projekte verwaltet und gesteuert werden können.

Und so können auch die Deployment-Schritte in der Pipeline mit Sloppys CLI-Tool automatisiert werden. Das Skript für diesen Schritt ist dann gerade einmal zwei Zeilen lang:

script:
- export SLOPPY_APITOKEN="$SLOPPY_APITOKEN"
- sloppy change --image docker/container:${CI_COMMIT_REF_NAME} umgebung/service/app

(Auszug aus der CI/CD-Konfiguration für Gitlab)

Zu verbessern wäre, dass dieser Pipelineschritt noch wartet, bis das Deployment erfolgreich abgeschlossen wurde und der Service gestartet werden konnte.

Doch wie bekommt die Pipeline die Sloppy CLI, sodass der Befehl sloppy überhaupt zur Verfügung steht? Entweder lädt und installiert die Pipeline die Binaries bei jeder Ausführung dieses Schrittes oder die Anwendung wird bereits in den zugrundeliegendeliegenden Container installiert und steht immer gleich zur Verfügung.

Für unser Zwecke habe ich den Container mal erstellt und auf Docker Hub verfügbar gemacht: dielok/sloppy-cicd. Viele Erfolg.

Sloppy hat einen genialen Ansatz als Cloud-Anbieter

Wenn ich Sloppy richtig verstehe, wollen sie ein Cloud-Anbieter sein, der grundsätzlich bei den Großen mitmischt. Und ich denke, dass werden sie auch, denn Sloppy nicht aus dem Silicon Valley sondern aus Köln zeigt mir gerade, was AWS, Google Cloud und Azure eigentlich falsch machen.

Sloppy ist im Wesentlichen ein Cloud-Anbieter, der auf den Kern der Sache konzentriert ist: Container (ob jetzt Pod oder Docker oder oder) spezifizieren und und den Cluster hochfahren. Das, sowie die restlichen Aufgaben, die es im Operrationsumfeld gibt, sollten nicht, eigentlich nicht und hätten es nie müssen: Hexenwerk sein.

Beispielsweise etwas, was vollkommen unterschätzt ist: Die sogenannte Docker-Compose-Datei. Im eigenen Team habe ich es miterlebt: Docker-Compose wird so ein bißchen als Spiellösung abgetan. Es ist aber ein komplett ausreichendes, universelles Interface um Cluster im Allgemeine zu definieren. Ob das jetzt Kubernetes, OpenShift oder sonst was läuft.

Sloppy hat dies sofort erkannt. Mindestens über deren CLI-Tool kann man diese Docker-Compose-Datei hochladen und damit den gesamten Cluster hochfahren und konfigurieren. Ich finde es schon alleine bemerkenswert, dass so eine kleine Firma ein beachtliches, einfach zu nutzendes CLI-Tool entwickelt und den Users zu Verfügung stellt.

Die GUI ist bereits jetzt sehr gut verwendbar. Es lassen sich verschiedene Projekte erstellen. Verschiedene Zonen. Ich kann die Container (standarmäßig vom Docker-Hub) definieren und die Instanzen skalieren. Rolling-Deployments kommen gleich mit.

In CI/CD Pipeline kann ich ohne viel Aufwand Deploymentsteps definieren, die die Anwendungen auf die jeweiligen Umgebungen deployen bis durch auf die Produktionsumgebung.

Ich weiß nicht, welche Wünsche das offen bleiben, für welchen Anwendungsfall.

Evtl. gibt es diverse Compliantsrichtlinien, die sich ohne die Konfigurationsmöglichkeiten eines AWS oder Azure nicht realisieren lassen. Okay. Aber das ist doch dann die eigentliche Niesche.

Eigentlich könnten man sogar darauf wetten, dass sich herausstellen wir, dass der Sloppy-Ansatz eigentlich für die Masse geeigneter ist, als die großen Cloud-Anbieter. Denn der Betrieb via Sloppy erfüllt im Prinzip alles, was 95% der aktuellen Nutzer derzeit bei AWS und Co. nur kompliziert und umständlich und nicht so einfach bekommen. Das macht Sloppy schon sehr gut.

DevOps: Versionierungsstrategie bei Continuous Delivery

Setzen wir die Version aus dem Quelltext heraus? Sollte die CI/CD-Pipeline die Version setzen und womöglich auch einen Tag automatisiert im Version Control System (VCS, z.B. Git, Mercurial, Subversion) setzen?

Achtung: Dieser Artikel ist eher Low-Level und für Build-Engineers, Entwickler und Architekten geeignet.

TL;DR: Wenn der Kunde mit kryptischen Buildnummern oder Hashwerten und keine Aussage über die Kompatibilität in der Versionsbezeichnung nötig ist, kann der einfach mit jedem Commit bis auf die Produktion automatisiert werden.

Meist ist dies jedoch nicht der Fall. Die Anwendung besteht wahrscheinlich aus einem Backend und einem Frontend, wenn es sich um einen einfachen Fall handelt. In vielen Fällen haben wir bereits Microservice Infrastruktur mit mehreren Servicen, die über Schnittstellen miteinander kommunizieren und voneinander abhängen. Abwärtskompatibilitäten und Breaking-Changes wollen durch die Versionierung transparent gemacht werden.

Doch Breaking Changes in einem Softwarestand zu identifizieren, ist aus meiner Sicht nicht automatisiert möglich. Eventuell könnte man experimentell über Schnittstellenkontrakte und automatisierte Tests Abwärtskompatibilität automatisiert testen, das ist aber nur eine fixe Idee eines zu kreativen Entwicklers. Auch zwischen Patch und Minor-Release zu unterscheiden ist Ermessenssache. Der Punkt ist, um abhängige Anwendungen mittels der Versionsnummer über Major-Updates und wahrscheinliche oder sogar sichere Kompatibilitätsprobleme zu informieren, benötige ich einen Menschen.

Zum Einsatz kommt natürlich Semantic Versioning — Sie wissen schon: major.minor.patch-snapshot.

Das ist der manuelle Teil. Der automatisierte Teil ist relativ unproblematisch: Jeder Commit im VCS erzeugt über die CI/CD-Pipeline ein Artefact mit der Buildnummer (wahlweise dem Commit-Hash). So etwas wie meine-anwendung:4711, wobei 4711 die Buildnummer ist.

Dieses Artefakt – sei es ein Docker-Image, eine EXE, ein Tar-Archiv, eine Jar-Datei, whatever – wird üblicherweise in einem Artefaktspeicher abgelegt (Artifactory, Nexus, Docker Registry, etc.) und von dort dann weiter auf die entsprechenden Umgebungen bis hin zur Produktion ausgerollt: „deployt“. Dort werden dann verschiedene Integrationstests, Ende-zu-Ende-Tests, Abnahmetests und so weiter ausgeführt.

Bei einer Codebasis, einer Anwendung, die gepflegt, weiterentwickelt und ausgeliefert wird, ist das easy. Die Buildnummer ist zentrale Wahrheit. Was aber wenn x Anwendungen entwickelt werden und in einem Ökosystem zusammenspielen müssen. Was bedeutet in diesem Kontext ein „neuer Build“? Anwendung-1 ist bei Build 6364 während Anwendung-12 erst bei Build 56 ist. Wie komme ich hier zu allgemeinen, automatisierten Testaussagen. Das behandeln wir mal in einem anderen Artikel.

Für unser einfaches Szenarion kommt jetzt wieder die manuelle Versionierung ins Spiel. Denn ich möchte meine neue Version nicht als 4711 veröffentlichen. Eine oft genutzte Eigenschaft meiner Schnittstelle stand in der letzten Version 1.2.3 noch zur Verfügung, ist aber jetzt nicht mehr dabei. Es ist Zeit für eine Version 2.0.0.

Wie benennen wir jetzt also den Build 4711 mit 2.0.0? Manuelles Ändern des Dateinamens? Sicher nicht. Aus meiner Sicht ist das Folgende am einfachsten: Wir nutzen Tags, falls uns VCS das hergibt (Git kann das natürlich).

Die Buildnummer ist nichts weiter als die fortlaufende Nummer der Pipelineausführung, durch die das Artefakt erzeugt wurde. Dieser Pipelinedurchlauf läuft auf einem bestimmten Codestand, der wiederum in einem Commit im VCS eindeutig enthalten ist.

Indem wir manuell einen Tag 2.0.0 auf diesen der Buildnummer 4711 eindeutig zugeordneten Commit setzen, lösen wir ein Event aus. Dieses Event triggert eine Pipeline, die nun das Artefakt nicht mit der Buildnummer, sondern der Tag-Bezeichnung versieht.

Jetzt ist es noch wichtig, die Artefakte vielleicht systematisch aufzuräumen, aber auch das ist ein Thema für einen weiteren Artikel.