jenkins workflow

Post on 14-Apr-2017

684 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

JENKINS WORKFLOW

15 DÉCEMBRE 2015

JEAN DETOEUFCONCEPTEUR-DÉVELOPPEUR

Passionné de nouvelles technologies

#jvm #docker #craftmanship #rpi #diy

SONDAGEIntégration continueLivraison continueDéploiement continu

INTÉGRATION CONTINUE

JENKINS

ET BEAUCOUP D'AUTRES

POURQUOI JENKINS ?

CI le plus utiliséExtensibleStableOpen SourceCommunautéLivraisons régulièresVieillissant par rapport à la concurrence ?

JOBS CLASSIQUES

COMMENT ENCHAÎNERDU BUILD AU DEPLOY ?

Histoire de faire du déploiement continu

EN CHAÎNANT LESJOBS

OUI, MAIS POURSUIVRE

L'ENCHAÎNEMENT ?

PIPELINE PLUGIN !

PROBLÈMEComplexe à mettre en oeuvreOn finit par avoir des jobs "étapes"File d'exécution impossible à lireUn job a des successeurs prédéterminésLe paramétrage se fait dans JenkinsSolution peu utilisable pour du déploiement continu

DÉPLOIEMENT CONTINULe but du déploiement continu est d'avoir une application

stable en production.

La chaine de livraison doit être automatisée au maximumpour réduire l'intervention humaine entre une modification

de code et sa livraison en production.

L'erreur est humaine

QUEL INTERVALE DE TEMPS ENTREDEUX MEP ?

Ce n'est pas le but premier du déploiement continu.

Pouvoir livrer rapidement ne veut pas dire livrerrégulièrement.

GO DELIVERYUn build est composé d'étapesChaque build peut être appliqué à un environnementFan-out-in (parallelisation des étapes)

GO DELIVERY

BONNES IDÉESParallèlisation des étapesEnvironnements de déploiementVisualisation du build et de l'étape en coursPossibilité d'avoir plusieurs repositories en entrée

PROBLÈMESConfiguration gérée dans l'outilPas de possibilité de scripter le jobDifficulté pour gérer plusieurs versions nécessitant desjobs différents

JENKINS WORKFLOWPLUGIN

PLUGIN(S)Ajout à une installation existanteNouveau type de job

SCRIPTER LE JOBET METTRE LE SCRIPT AVEC LES

SOURCES

PIPELINE AS CODE !

SCRIPT STANDARDEcrit en shellS'exécute sur un noeud (maître ou esclave)

JENKINSFILEFichier de build en Groovy

Du build au deploy dans un fichier compréhensible

Permet une orchestration plus avancée

Convention de nommage : Jenkinsfilenode { git url: 'https://github.com/spring-projects/spring-petclinic.git' def mvnHome = tool 'M3' sh "${mvnHome}/bin/mvn -B verify" }

JENKINSFILELe base de code déclare elle-même comment s'installerDifférentes versions (tags/branches/commits) peuventavoir des manières différentes de s'installernode { git url: 'https://github.com/spring-projects/spring-petclinic.git' def mvnHome = tool 'M3' sh "${mvnHome}/bin/mvn -B verify" }

ACTIONS FOURNIESPAR WORKFLOW

COMMANDE SHELLsh 'ls /tmp'

bat 'dir C:\tmp'

Pour reprendre un script standard, il suffit de reprendretoutes les lignes du script comme ceci

ECHO (PRINT)echo 'Compilation'

TRY-CATCH-FINALLYtry { checkpoint('Before production') } catch (NoSuchMethodError _) { echo 'Checkpoint feature available in CloudBees Jenkins Enterprise.'}

FOR-LOOPSfiles.each{ file -> sh "check.sh $file" }

for num in 1..10 sh "echo $num" }

OUTILSdef mvn(args) { sh "${tool 'Maven 3.x'}/bin/mvn ${args}" }

mvn 'clean install'

VALIDATION HUMAINEinput 'Est-ce que la page ${url} est correcte ?'

Si cette validation intervient avant le déploiement, on fait dela livraison continue

CHOIX DU NOEUDD'EXÉCUTION

node('unix && 64bit') { sh 'make install' }

PARAMÈTRESEXPOSÉES SOUS FORME DE

VARIABLES D'ENVIRONNEMENTShell

$VAR

Groovyenv.VAR

PARALLÈLISATION

PARALLELfor (int i = 0; i < splits.size(); i++) { branches["split${i}"] = { node('remote') { sh 'rm -rf *' sh "${tool 'M3'}/bin/mvn -B -Dmaven.test.failure.ignore test" } } } parallel branches

parallel prend une map en paramètrela clé représente le nom de la branchela valeur correspond au bloc de code à exécuter

PARALLEL

STAGEPermet de séparer le phases du jobPermet de limiter le nombre d'exécutions parallèles

stage 'build' sh "${tool 'M3'}/bin/mvn clean install" stage concurrency: 1, name: 'deploy' sh 'mv target/app.war /tmp/webapps/'

STAGEstage 'build' sh "${tool 'M3'}/bin/mvn clean install" stage name: 'deploy', concurrency: 1 sh 'mv target/app.war /tmp'

Tant que le stage deploy n'est pas terminé, les exécutionssuivantes s'arrêtent avant deploySi plusieurs exécutions sont en attente de deploy, c'est ladernière qui est retenue.

STAGE

CHARGEMENT D'UN FICHIER DESCRIPT

node{ def install = load 'install.groovy' install.main() }

Permet de diviser le script de build en plusieurs parties

SUIVI À L'IHM : OPEN SOURCE

Liens pour afficher les logs de chaque étape

SUIVI À L'IHM : CLOUDBEES EDITION

LONGUE INSTALLATIONLes builds de Workflow survivent à un redémarrage deJenkinsLe thread d'orchestration ne s'exécute que pour lancer laprochaine tache

RÉSUMÉUne orchestration intégrée à la base de codeUn langage expressif (DSL workflow et Groovy)Parallèlisation et distribution des tâchesPipeline de déploiement continu

EST-CE QU'ON A LE TEMPS POURUNE DÉMO ?

MULTIBRANCH

Jenkins a uniquement besoin de connaître l'URL durepository

MULTIBRANCHPour chaque branche à la racine de ce repository doit se

trouver le fichier Jenkinsfile

Les branches sont scrutées régulièrement et mises à jour etlancées

On peut utiliser un hook pour lancer les builds

JENKINS SLAVESBesoin d'installer des outils

Le bon JDK, la version de Maven qu'il me faut, gradle ? sbt ?compilateur ?

DOCKER TO THE RESCUE !

DOCKER TO THE RESCUE !

Docker est la solution à tout de toutes manières

WORKFLOW DANS UNE IMAGEDOCKER

docker.image('maven:3.3.3-jdk-8').inside { sh 'mvn -B clean install' }

Le répertoire courant dans docker est le workspace Jenkins

Montage du workspace dans un volume docker

Plus de problèmes d'outils, mis à part Docker qui doit êtreinstallé sur les slaves

Le container est supprimé après son exécution

FAIRE DES IMAGES DOCKER DANSJENKINS

DOCKER BUILDnode { git scm // Récupérer le repository git en mode multibranch def myEnv = docker.build 'my-environment:snapshot' myEnv.push() }

DOCKER BUILDnode { git scm // Récupérer le repository git en mode multibranch def myEnv = docker.build "my-environment:${env.BUILD_TAG}" myEnv.push() }

Utilisation du tag git pour pousser dans le registry

DOCKER POUR TESTERnode { git scm docker.image('mysql').withRun('-p 81:3126') {c -> sh './test-with-local-db' } }

On veut exécuter le corps du withRun alors que l'imagemysql tourne

Le withRun prend optionnellement les paramètres dudocker run

Adapté aux tests d'intégration

DOCKER REGISTRYnode { docker.withRegistry('https://docker.mycorp.com/', 'docker-login'){ git scm docker.build('myapp').push('latest') } }

Possibilité d'utiliser un registry privé

On passe des credentials enregistrés dans Jenkins

DOCKER SERVERdocker.withServer('tcp://swarm.mycorp.com:2376', 'swarm-certs'){ docker.image('httpd').withRun('-p 8080:80') {c -> sh "curl -i http://${hostIp(c)}:8080/" } } def hostIp(container) { sh "docker inspect -f {{.Node.Ip}} ${container.id} > hostIp" readFile('hostIp').trim() }

Possibilité de déléguer à un serveur docker (swarm ou autre)

Le client docker doit être installé

A utiliser si le slave ne peut pas supporter l'application àtester

QUESTIONS ?

MERCI POUR VOTRE ÉCOUTE

Cette présentation :

@thebignetthebignetthebignet

talk-jenkins-workflow

top related