Simple Jenkins Pipeline avec Marathon et Mesos

Pipeline Jenkins simple avec Marathon et Mesos

1. introduction

Dans cet article, nous allons mettre en œuvre un pipeline de livraison continue simple avecJenkins,Marathon etMesos.

Dans un premier temps, nous donnerons un aperçu de haut niveau de la pile technologique et de l’architecture, en expliquant comment tout s’intègre. Ensuite, nous passerons à un exemple pratique, étape par étape.

Le résultat sera un pipeline Jenkins entièrement automatisé, déployant notre application sur notre cluster Mesos à l'aide de Marathon.

2. Vue d'ensemble de la pile technologique

Lorsque nous travaillons avec des conteneurs et des architectures de microservices, nous sommes confrontés à de nouveaux problèmes opérationnels que nous n'aurions pas pu résoudre avec des piles plus traditionnelles.

Par exemple, lors du déploiement sur un cluster, nous devons gérer la mise à l'échelle, le basculement, la mise en réseau, etc. Ces problèmes informatiques distribués difficiles peuvent être résolus avec des noyaux distribués et des ordonnanceurs, comme Apache Mesos et Marathon.

2.1. Mesos

Mesos, en termes simples, peut être considéré comme le serveur unique sur lequel nos applications seront exécutées. En réalité, nous avons un cluster, mais c'est cette abstraction qui le rend si utile.

2.2. Marathon

Marathon est le cadre utilisé pour déployer nos applications sur Mesos, résolvant ainsi des problèmes difficiles pour nous (vérification de l'intégrité, mise à l'échelle automatique, basculement, surveillance, etc.).

3. Configuration et installation

Cet article suppose que vous avez déjà Jenkins, Mesos et Marathon en cours d'exécution. Si ce n'est pas le cas, consultez la documentation officielle de chacun d'eux pour savoir comment les configurer. Sans cela, vous ne pourrez mettre en œuvre aucune des étapes du guide.

4. Notre pipeline de livraison

Nous allons créer le pipeline Jenkins suivant:

 

image

Il n'y a rien de particulièrement complexe dans cette approche - elle est synonyme de flux de la plupart des pipelines de CD modernes. Dans notre cas, la construction signifie la conteneurisation de l'application et le déploiement, l'utilisation de Marathon pour la planifier sur un cluster Mesos.

5. Tester et créer notre application

La première étape consiste à créer et à tester notre application. Pour que les choses restent simples, l’application avec laquelle nous allons travailler est une application Spring Boot. Pour cette raison, notre artefact résultant sera un fichier jar exécutable. Il n’aura aucune dépendance externe autre que JRE, ce qui le rend très simple à exécuter.

5.1. Créer notre travail

La première chose que nous voulons faire est de créer notre travail Jenkins. Sélectionnez "Nouvel élément" dans la barre de navigation de gauche, puis sélectionnez créer un projet de style libre en le nommant "marathon-mesos-demo":

image

5.2. Intégration avec Git

Ensuite, configurons-le surclone the Github repository contenant notre application:

image

Par souci de simplicité, notre référentiel est public, ce qui signifie que nous pouvons cloner via https. Si ce n'était pas le cas et que nous clonions via SSH, il y aurait une étape supplémentaire pour mettre en place un SSH utilisateur et clé privée, au-delà de la portée de cet article.

5.3. Configurer les déclencheurs de compilation

Ensuite, configurons quelques déclencheurs de compilation afin que notre tâche interroge git pour de nouveaux commits toutes les minutes:

image

5.4. Générer notre script de construction

Nous pouvons maintenant dire à notre travail d’exécuter un script shell lorsqu’il s’exécute. Comme nous travaillons avec un simple projet Spring Boot Maven, tout ce que nous avons à faire est d'exécuter la commande «mvn clean install». Cela exécutera tous les tests et construira notre fichier exécutable jar:

image

5.5. Construire notre projet

Maintenant que nous avons configuré le début de notre pipeline, déclenchons-le manuellement en cliquant sur "Créer maintenant" sur la tâche. Une fois le travail terminé, nous pouvons confirmer qu'il a réussi en le marquant en bleu.

6. Conteneurisation de notre application

Passons à la prochaine étape de notre pipeline, qui consiste à empaqueter et à publier notre application avec Docker. Nous devons utiliser Docker car les conteneurs sont spécifiquement gérés par Marathon. Ce n’est pas déraisonnable, car pratiquement tout peut s’exécuter dans un conteneur. Il est plus facile pour un outil comme Marathon de travailler avec l’abstraction accordée par ces derniers.

6.1. Création du Dockerfile

Commençons par créer unDockerfile à la racine du projet. Essentiellement, un fichier Docker est un fichier contenant des instructions au Docker Deamon sur la manière de construire une image:

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

L'image que nous construisons est simple: elle ne contient qu'un jar exécutable et une commande shell qui l'exécutera au démarrage du conteneur. Nous devons également nous assurer que nous exposons le port que notre application écoutera, dans ce cas-ci «8082».

6.2. Publication de l'image

Maintenant que nous sommes en mesure de construire notre image, créons un simple script bash qui le construit et le publie dans notre référentiel privéDocker Hub, et le met à la racine de notre projet:

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

Vous devrez peut-être transmettre votre image au registre public ou au registre privé.

La variable d'environnement$BUILD_NUMBER est remplie par Jenkins, incrémentée à chaque build. Bien que légèrement fragile, c’est un moyen rapide d’augmenter le nombre de versions de chaque version. Le$DOCKER_PASSWORD est également rempli par Jenkins, et dans ce cas, nous utiliserons lesEnvInject plugin pour le garder secret.

Bien que nous puissions stocker ce script directement dans Jenkins, il est préférable qu'il reste dans le contrôle de version, car il peut ensuite être versionné et audité avec le reste de notre projet.

6.3. Construire et publier sur Jenkins

Modifions maintenant notre travail Jenkins pour qu'il exécute «Dockerise.sh» après la création du fichier jar:

 

image

Ensuite, exécutons notre tâche pour confirmer à nouveau, en confirmant que tout fonctionne en devenant bleu.

7. Déployer notre image

Notre pipeline est presque terminé. Il ne reste plus qu’une étape: utiliser Marathon pour déployer notre application sur notre cluster Mesos.

Jenkins est fourni avec le plug-in “https://wiki.jenkins-ci.org/display/JENKINS/Marathon+Plugin[Deploy with Marathon]”. Cela agit comme une enveloppe autour de l'API Marathon, ce qui le rend plus facile que si vous utilisiez des scripts shell traditionnels. Vous pouvez l'installer via le gestionnaire de plugins.

7.1. Création de notre fichier Marathon.Json

Avant de pouvoir utiliser le plug-in Marathon, nous devons créer un fichier «marathon.json» et le stocker dans la racine du projet. C'est parce que le plugin en dépend.

Ce fichier: «marathon.json» contient unMesos Application Definition. Il s'agit d'une description d'un service (application) de longue durée que nous souhaitons exécuter. En fin de compte, le plugin Jenkins Marathon POSTERA le contenu du fichier sur le point de terminaison de Marathon/v2/apps. Marathon programmera alors à son tour l’application définie pour fonctionner sur Mesos:

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

C'est la configuration la plus simple que nous puissions donner pour une application conteneurisée.

La propriété: «portMappings» doit être définie correctement afin de rendre notre application accessible depuis notre esclave Mesos. Cela signifie essentiellement, mapper le port du conteneur8082, à un port aléatoire sur l'hôte (esclave mesos) afin que nous puissions parler à notre application depuis le monde extérieur. Après avoir déployé votre application, Marathon nous dira ce que ce port a utilisé.

7.2. Ajout d'une étape de build de déploiement Marathon

Ajoutons une action post-build Déploiement Marathon à notre mission:

image

Notez que nous indiquons au plugin où s'exécute Marathon, dans ce cas "localhost: 8081". Nous lui communiquons également l’image que nous souhaitons déployer. C'est ce par quoi le champ "image" vide de notre fichier est remplacé.

Maintenant que nous avons créé la dernière étape de notre pipeline, exécutons notre tâche une fois de plus et confirmons qu'elle est toujours en cours, cette fois avec l'étape supplémentaire qui consiste à envoyer notre candidature à Marathon.

7.3. Vérification de notre déploiement à Marathon

Maintenant qu'il est déployé, jetons un coup d'œil dans l'interface utilisateur de Marathon:

 

image

Comme nous pouvons le constater, votre application n'est pas affichée dans l'interface utilisateur. Pour y accéder, il suffit de vérifier l'hôte et le port qui lui ont été attribués:

image

Dans ce cas, il a été alloué au hasard le port 31143 sur localhost, qui sera mappé en interne au port 8082 dans notre conteneur tel que configuré dans la définition de l'application. Nous pouvons ensuite visiter cette URL dans votre navigateur pour confirmer que l'application est servie correctement.

8. Conclusion

Dans cet article, nous avons créé un pipeline de livraison continue simple à l'aide de Jenkins, Marathon et Mesos. Chaque fois que nous demandons une modification de notre code, il sera exécuté dans un environnement quelques minutes plus tard.

Les articles suivants de cette série couvriront des sujets plus avancés sur Marathon, tels que la vérification de l'état de santé des applications, la mise à l'échelle, le basculement. D'autres cas d'utilisation pour Mesos, tels que le traitement par lots, peuvent également être couverts.

Le code source de notre application est disponible surover on GitHub; c'est un projet Maven qui devrait pouvoir fonctionner tel quel.