Einfache Jenkins Pipeline mit Marathon und Mesos

1. Einleitung

In diesem Artikel implementieren wir eine einfache Continuous Delivery-Pipeline mit Jenkins, Marathon und Mesos.

Zunächst geben wir einen allgemeinen Überblick über den Technologie-Stack und die Architektur und erklären, wie alles zusammenpasst. Anschließend gehen wir Schritt für Schritt zu einem praktischen Beispiel über.

Das Ergebnis wird eine vollautomatische Jenkins-Pipeline sein, die unsere Anwendung mithilfe von Marathon in unserem Mesos-Cluster bereitstellt.

2. Überblick über den Technologie-Stack

Bei der Arbeit mit Containern und Microservice-Architekturen treten neue Betriebsprobleme auf, die wir mit herkömmlichen Stacks nicht hätten lösen können.

Bei der Bereitstellung in einem Cluster müssen wir uns beispielsweise mit Skalierung, Failover, Netzwerk und mehr befassen. Diese schwierigen, verteilten Computerprobleme können mit verteilten Kerneln und Schedulern wie Apache Mesos und Marathon gelöst werden.

2.1. Mesos

Mesos kann im einfachsten Sinne als der einzige Server angesehen werden, auf dem unsere Anwendungen ausgeführt werden. In Wirklichkeit haben wir einen Cluster, aber es ist diese Abstraktion, die ihn so nützlich macht.

2.2. Marathon

Marathon ist das Framework, mit dem unsere Anwendungen auf Mesos bereitgestellt werden, um schwierige Probleme für uns zu lösen (Integritätsprüfung, automatische Skalierung, Failover, Überwachung usw.).

3. Einrichtung und Installation

In diesem Artikel wird davon ausgegangen, dass bereits Jenkins, Mesos und Marathon laufen. Wenn dies nicht der Fall ist, konsultieren Sie die offizielle Dokumentation für jeden von ihnen, um zu erfahren, wie Sie sie einrichten. Ohne dies können Sie keinen der Schritte in der Anleitung ausführen.

4. Unsere Lieferpipeline

Wir werden die folgende Jenkins-Pipeline erstellen:

Dieser Ansatz ist nicht besonders komplex - er ist gleichbedeutend mit dem Fluss der meisten modernen CD-Pipelines. In unserem Fall bedeutet das Erstellen das Containerisieren der Anwendung und das Bereitstellen das Verwenden von Marathon, um sie in einem Mesos-Cluster zu planen.

5. Testen und Erstellen unserer Anwendung

Der erste Schritt besteht darin, unsere Anwendung zu erstellen und zu testen. Um die Dinge einfach zu halten, ist die Anwendung, mit der wir arbeiten werden, eine Spring Boot-Anwendung. Aus diesem Grund wird unser resultierendes Artefakt ein ausführbares Glas sein. Es gibt keine anderen externen Abhängigkeiten als die JRE, was die Ausführung sehr einfach macht.

5.1. Unseren Job schaffen

Das erste, was wir tun möchten, ist, unseren Jenkins-Job zu schaffen. Wählen Sie in der linken Navigationsleiste "Neues Element" aus und wählen Sie "Freestyle-Projekt erstellen" mit dem Namen " Marathon-Mesos-Demo " :

5.2. Integration mit Git

Als nächstes konfigurieren wir es so, dass es das Github-Repository klont, das unsere Anwendung enthält:

Der Einfachheit halber ist unser Repository öffentlich, was bedeutet, dass wir über https klonen können . Wenn dies nicht der Fall wäre und wir über SSH klonen würden, gäbe es einen zusätzlichen Schritt, um einen SSH-Benutzer und einen privaten Schlüssel einzurichten, die über den Rahmen dieses Artikels hinausgehen.

5.3. Einrichten von Build-Triggern

Als nächstes richten wir einige Build-Trigger ein, damit unser Job jede Minute git nach neuen Commits abfragt:

5.4. Generieren unseres Build-Skripts

Wir können unseren Job jetzt anweisen, ein Shell-Skript auszuführen, wenn es ausgeführt wird. Da wir mit einem einfachen Spring Boot Maven-Projekt arbeiten, müssen wir nur den Befehl „ mvn clean install “ ausführen . Dadurch werden alle Tests ausgeführt und unser ausführbares JAR erstellt :

5.5. Aufbau unseres Projekts

Nachdem wir den Anfang unserer Pipeline eingerichtet haben, können Sie ihn manuell auslösen, indem Sie im Job auf "Jetzt erstellen" klicken. Sobald der Auftrag abgeschlossen ist, können wir bestätigen, dass er bestanden wurde, indem er als blau markiert wird.

6. Containerisierung unserer Anwendung

Fahren wir mit der nächsten Phase unserer Pipeline fort, nämlich dem Verpacken und Veröffentlichen unserer Anwendung mit Docker. Wir müssen Docker verwenden, da Container genau das sind, was Marathon verwaltet. Dies ist nicht unangemessen, da praktisch alles in einem Container ausgeführt werden kann. Für ein Tool wie Marathon ist es einfacher, mit der von diesen gewährten Abstraktion zu arbeiten.

6.1. Dockerfile erstellen

Lassen Sie uns zunächst eine Docker-Datei im Projektstamm erstellen. Im Wesentlichen ist eine Docker-Datei eine Datei, die Anweisungen an Docker Deamon zum Erstellen eines Images enthält:

FROM openjdk:8-jre-alpine ADD target/mesos-marathon-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8082 ENTRYPOINT ["java","-jar","/app.jar"]

The image we are building is simple – all it contains is an executable jar and a shell command which will execute it when the container starts. We also have to make sure that we are exposing the port that our application will listen on, in this case ‘8082'.

6.2. Publishing the Image

Now that we are able to build our image, let's create a simple bash script which builds and publishes it to our private Docker Hub repository, and put it in our project root:

#!/usr/bin/env bash set -e docker login -u baeldung -p $DOCKER_PASSWORD docker build -t baeldung/mesos-marathon-demo:$BUILD_NUMBER . docker push baeldung/mesos-marathon-demo:$BUILD_NUMBER 

You might need to push your image to the public docker registry or your private one.

The $BUILD_NUMBER environment variable is populated by Jenkins, incrementing with every build. Although slightly brittle, it is a quick way of getting each build to increase in version number. The $DOCKER_PASSWORD is also populated by Jenkins, and in this case, we will make use of the EnvInject plugin in order to keep it secret.

Whilst we could store this script directly in Jenkins, it's better practice for it to remain in version control, as it can then be versioned and audited alongside the rest of our project.

6.3. Building and Publishing on Jenkins

Now let's modify our Jenkins job so it runs “Dockerise.sh” after building the jar:

And then, let's run our job to confirm again, confirming everything is working by it going blue.

7. Deploying Our Image

Our pipeline is nearly complete. There is only one more stage, which is to use Marathon to deploy our application to our Mesos cluster.

Jenkins comes with a “Deploy with Marathon” plugin. This acts as a wrapper around the Marathon API, making it easier than it would be when working with traditional shell scripting. You can install it via the plugin manager.

7.1. Creating Our Marathon.Json File

Before we can use the Marathon plugin, we need to create a “marathon.json” file, and store it in our project root. This is because the plugin is dependent on it.

This file: “marathon.json” contains a Mesos Application Definition. This is a description of a long-running service (application) that we want to run. Ultimately, the Jenkins Marathon plugin will POST the contents of the file to the Marathon /v2/apps endpoint. Marathon will then in turn schedule the defined application to run on Mesos:

{ "id": "mesos-marathon-demo", "container": { "type": "DOCKER", "docker": { "image": "", "network": "BRIDGE", "portMappings": [ { "containerPort": 8082, "hostPort": 0 } ] } } }

This is the simplest configuration we can give for a containerized application.

The property: “portMappings” needs to be set correctly in order to make our application accessible from our Mesos slave. It basically means, map the container port 8082, to a random port on the host (mesos slave) so we can talk to our application from the outside world. After deploying our application, Marathon will tell us what that port used.

7.2. Adding a Marathon Deployment Build Step

Let's add a Marathon Deployment post build action to our job:

Notice we're telling the plugin where Marathon is running, in this case ‘localhost:8081'. We're also telling it the image we want to deploy. This is what the empty “image” field in our file get's replaced with.

Now we've created the final stage of our pipeline, let's run our job one more time and confirm that it's still passing, this time with the extra step where it sends our application to Marathon.

7.3. Verifying Our Deployment in Marathon

Now it's been deployed, let's take a look in the Marathon UI:

As we can see, our application is now shown in the UI. In order to access it, we just need to check what host and port it has been assigned:

In diesem Fall wurde dem Port 31143 auf localhost zufällig zugewiesen, der intern dem Port 8082 in unserem Container zugeordnet wird, wie in der Anwendungsdefinition konfiguriert. Wir können diese URL dann in unserem Browser besuchen, um zu bestätigen, dass die Anwendung korrekt bereitgestellt wird.

8. Fazit

In diesem Artikel haben wir eine einfache Continuous Delivery-Pipeline mit Jenkins, Marathon und Mesos erstellt. Immer wenn wir eine Änderung an unserem Code vornehmen, wird dieser einige Minuten später in einer Umgebung ausgeführt.

In späteren Artikeln dieser Reihe werden fortgeschrittenere Marathon-Themen behandelt, z. B. Überprüfung des Anwendungszustands, Skalierung und Failover. Andere Anwendungsfälle für Mesos, wie z. B. die Stapelverarbeitung, können ebenfalls behandelt werden.

Der Quellcode für unsere Anwendung ist auf GitHub verfügbar. Dies ist ein Maven-Projekt, das so ausgeführt werden sollte, wie es ist.