Jenkins/GitLab+Docker release automation

Salut les geeks!

Chez mon client on essaie de se mettre à la page en utilisant Jenkins, GitLab et CA Release Automation. Bref on code, on commit dans GitLab, Jenkins lance un build dans la foulée et fait aussi tourner un projet de test, de façon automatisée. Je dois faire une présentation à ce propos dans ma boîte, et je kifferais bien de pouvoir faire une présentation en live avec un POC.

Pour ça j’attends de savoir si je vais avoir accès à une VM Linux dédiée, mais en attendant je pense que je peux déjà commencer les bases, à savoir, dans le pire des cas:

  • installer GitLab sur mon laptop Windows via Docker
  • créer un projet de test avec Java/Cucumber
  • SOIT installer Jenkins via Docker pour faire tourner ce projet
  • SOIT, plus ambitieux, utiliser GitLab CI/CD, que je connais pas du tout
  • BONUS STAGE: utiliser GitLab CD pour:
  1. copier des fichiers depuis le repo Git sur un serveur cible
  2. lancer un script de déploiement via un user spécifique sur la même machine

Est-ce que vous avez de l’expérience là-dedans ou des tutos concrets à me recommander sur ce bazar? J’ai déjà fait quelques petits pipelines sur Jenkins mais je débute avec Docker et GitLab, donc c’est pas ultra évident :wink:

Quelques pistes pour t’aider dans ton aventure « Continuous Integration ».

Le premier conseil que je peux te donner c’est d’oublier, au moins dans un premier temps, Docker. Un outil comme Jenkins, et dans une certaine mesure aussi Gitlab, ça n’est pas un outil adapté à la conteneurisation. Jenkins est historiquement un fork d’un projet nommé Hudson, et ça commence à avoir plus de dix ans. Plein de choses ne sont pas bien foutues pour les conteneurs.

Du coup je te conseille de viser une installation avec 1 outil = 1 VM. Si c’est trop compliqué d’avoir ça, tu peux collocaliser les outils sur une seule VM. Pour un prototype ça ira très bien. Mais sur le long terme tu te rendra compte que ça pose des problèmes en production. Chaque outil a des besoins assez différents et concurrents en ressources.

Le second conseil que je te donnerais c’est d’ajouter un gestionnaire d’artefacts à ton architecture (à moins que Release Automation fasse ça, je ne connais pas cet outil). Les deux pistes Open Source les plus fiables sont JFrog Artifactory et Sonatype Nexus (ton choix sera dicté très probablement par les types de dépôts que tu veux et que tu trouves dans les versions communautaires de ces outils : Python, NodeJS/NPM, Maven2, Docker, yum…).

Par rapport à ta question sur GitlabCI pour remplacer Jenkins, je pense que c’est une bonne idée pour un prototype. Les pipelines GitlabCI sont bien documentés, et c’est un outil désormais assez connu. En face, Jenkins est un peu vieillissant, mais très communautaire, avec des tonnes de plugins utiles et d’intégrations. Si je devais monter une architecture de zéro, sans contraintes d’existant, je pencherais quand même vers GitlabCI.

Troisième conseil, fait simple. De l’installation « prototype » à faire ton propre Cloudbees maison, il y a un gouffre dans lequel tu peux vite tomber (oh un plugin cool, oh une automatisation sympa…). Commence petit. A chaque fois que tu te dis « je vais rajouter cette fonctionnalité », pèse bien le ratio travail/gain. Et ce conseil ne concerne pas que la partie technique. C’est très tentant également de faire compliqué sur l’organisation (en équipes, en projets, standardiser le nommage etc.) : là aussi parfois il faut savoir commencer simple, quitte à avoir conscience qu’il faudra dans quelques mois refaire du ménage et mettre en place des stratégies.

Comme disait Dijsktra (le mathématicien, pas l’espion) : « early optimization is the root of all evil! »

Si tu veux te documenter sur ce sujet je te conseille très fortement d’aller regarder ce que Martin Fowler a écrit. C’est LE mec à suivre pour ce qui concerne la CI/CD. Côté France, tu devrais aussi t’intéresser à ce que publie Nicolas de Loof, Monsieur Cloudbees : https://twitter.com/ndeloof.

Tu peux aussi regarder les conférences Devoxx sur Youtube, il y a plein de très bonne pratiques à y trouver notamment par les gens de Cloudbees ou de JFrog.

Une vidéo à voir avant de jouer avec Jenkins notamment :

Pour info, c’est un sujet sur lequel je bosse pas mal aussi bien techniquement qu’en termes de méthodologie la CI/CD. Je ne veux pas t’écrouler sous des réponses technico-techniques et trop pointues, il faut que tu mettes les mains dans le cambouis pour te faire tes propres idées. Mais si tu galères sur un point technique, ou si tu veux une relecture de présentation, n’hésite pas à PM.

2 « J'aime »

J’ai passe pas mal d’heures a faire tout ca pour pour avoir un pipeline sous Jenkins pour nos jeux (UE4 et Unity).
Assez different, mais j’ai les bases, assez pour essayer de repondre a quelques questions :slight_smile:

Je n’ai pas grand chose a rajouter a ce qui a ete dit avant, mais je mentionne quand meme une alternative a Jenkins et Gitlab CI : TeamCity, qui a depuis peu une offre gratuite plus interessante qu’avant.

1 « J'aime »

Effectivement je :+1: les outils JetBrains. Je n’ai jamais utilisé TeamCity, mais si c’est du même acabit que leurs autres softs ça doit être très intéressant à tester. Par contre il n’y a pas, à ma connaissance, de version communautaire. Et il y aura probablement un peu moins de littérature que sur les autres outils.

En effet pas de version communautaire. Leur offre gratuite offre 100 configurations de builds differentes, et 3 build agents. Le prix grimpe assez vite derriere.

Mais ils proposent des integrations natives avec leurs autres outils, comme YouTrack ou Resharper, et ont aussi un plugin visual studio.

Moins de litterature que Jenkins en effet, mais leur doc est assez fournie, bien ecrite, et centralisee. Pas comme Jenkins ou tu dois aller chercher les infos a droite a gauche (quand elle existe :stuck_out_tongue: )

En tant qu’utilisateur et en grosse partie administrateur de Jenkins depuis 10 ans et de Teamcity depuis genre 7 ans, si tu veux aller vite prends Teamcity. C’est fiable, c’est très fiable, vraiment très fiable c’est pas spécialement cher pour une entreprise si t’as pas besoin de centaines d’agents et c’est facile à administrer. C’est relativement facile de se former dessus, la doc est top. Et c’est bourré de chouettes fonctionnalités qui rendent la vie plus facile. Par contre, c’est pas un produit si connu que ça par rapport aux autres produits du genre.
Sinon, si t’as zéro budget pour ton IC, à part les VMs, Jenkins fait l’affaire. Mais les personnes qui vont l’administrer vont perdre du temps pour des bêtises. C’est pas fiable, les plugins sont quasi tous fait par des nobody et ça casse régulièrement. Ça s’administre avec des pinces chirurgicales et avec beaucoup de sauvegardes. La doc est misérable, ta meilleure documentation sera Stack Overflow. Et puis Jenkins est truffé de piège, genre les dépendances qui si t’as fait une faute de frappe échouent silencieusement, Maven qui se comporte bizarrement dessus (conf de proxy ignorée au pif) et des tas d’autres trucs qui te font détester la vie. Malgré tout, si vous n’avez pas de budget pour les licences, ça peut se tenir.

En ce qui concerne les deux, au niveau du setup, tu vas vouloir séparer ton master, la base de données du master (si Teamcity) et tes agents sur des VMs différentes. Les trois n’auront pas besoin du même rythme de sauvegarde et des mêmes perfs. Faut sauvegarder souvent le master et sa base, c’est ce qui va porter toute la valeur de ton intégration continue. Faut prévoir de bonnes perfs disques pour le master des deux. Le master va passer son temps à écrire des livrables sur le disque, ses logs aussi. Niveau RAM c’est pas spécialement gourmand, autant pour Teamcity que Jenkins, genre 1 ou 2 Go au doigt mouillé sous Linux, 2 Go si tu veux avoir un gros cache disque sous linux.
À l’opposé, faut partir du principe que les agents sont totalement jetables. Le top du top moderne, c’est de les faire tourner sur docker, comme ça tu documentes la stack logicielle dont t’as besoin et les versions. Si t’as des sysadmins allergiques à docker, l’idéal est d’utiliser des trucs style ansible, puppet et compagnie pour documenter ce qui est installé dessus. L’antipattern ultime étant de pas être sûr de ce qui est installé dessus et de devoir cloner la VM à l’infini parce qu’on sait plus trop la recréer. En général, tu vas vouloir avoir des VMs avec plusieurs CPUs sur les agents, et du CPU costaud. Pour autant que j’aie vu, c’est rare d’avoir des tests qui bourrinent les disques, ou alors c’est de toute façon hébergé sur des VMs dédiées.

Sur une IC, faut jamais au grand jamais mettre d’agents/slaves/nodes qui tournent sur le master. Ça fait des problèmes de perfs louches, surtout sur Jenkins qui héberge sa base de données en interne.

Bref, hésite pas à poser des questions :wink:

J’ai du mal à comprendre le besoin exact et la première impression que j’ai en lisant le message original c’est qu’effectivement il vaudrait mieux viser plus simple.

Pour un projet open source comme Karaoke Mugen on utilise GitlabCI pour a peu près tout ce qui bouge (et aussi ce qui ne bouge pas)

Moi j’ai toujours été aussi de l’école d’aller au plus simple, surtout que GitlabCI avec gitlab-runner est quand même plutôt bien foutu mine de rien et très bien documenté comme dit plus haut. Après je connais pas exactement les besoins ni comment est faite l’appli, mais rien que pour un POC ça pourrait être suffisant que d’utiliser uniquement GitlabCI à mon humble avis

1 « J'aime »

Waw merci les gens, je vois qu’on peut toujours compter sur la Zone :smiley: Je vais détailler un peu plus mes besoins, parce qu’effectivement on est déjà parti un peu loin :stuck_out_tongue:

Dans un mois je dois faire une petite présentation d’une heure à une dizaine de personnes de ma boîte. On travaille comme consultants sur une plate-forme bancaire, et j’aimerais leur parler de l’automatisation des tests sur un composant web de cette plateforme. Durant la présentation, j’aimerais leur faire une toute petite démo en live. DONC:
On a un serveur de test qui fait tourner l’appli
J’ai mon laptop, et/ou une petite VM Linux

Je prévois de créer un petit projet de test avec Java/Cucumber, qui fera des appels vers les services web de notre serveur de test.

VERSION SIMPLE:

  • j’installe Jenkins, que je connais un tout petit peu, soit dans une VM soit dans un Docker (ça me permettrait de montrer aussi Docker à la team)
  • je crée un pipeline qui run mon projet de test et qui affiche les résultats avec le plugin Jenkins qui va bien

VERSION BONUS:

  • J’installe un agent de release automation sur notre serveur de test
  • Je crée un pipeline un peu plus gros, qui appelle genre un script helloWorld.sh sur le serveur, pour simuler un nouveau déploiement
  • le pipeline, après le fake déploiement, fait tourner mon projet de test pour montrer que tout roule au poil

Bref ici c’est juste pour montrer un peu ce qui peut être fait chez les clients, c’est un mini-proto « jetable » juste pour une présentation. Certains des gars qui seront là ont déjà vu tourner un truc similaire chez d’autres clients. Disons que c’est un peu pour le fun et pour me faire la main, mais ça n’a pas vocation à être maintenu dans le temps, donc un truc quick & dirty fera très très bien l’affaire :slight_smile:
Du coup, si GitLab est payant, c’est déjà out :stuck_out_tongue:

C’était vrai il y a dix ans quand Kohsuke était le seul vrai mainteneur Depuis que Cloudbees est mainteneur du projet, c’est globalement faux. La LTS est très fiable.

Pour les plugins, avant d’en utiliser un il faut regarder sur le site le nombre de téléchargements, et les derniers commits. La plupart des plugins standards sont très bien maintenus. Cependant, pour garder Jenkins stable et facile à administrer, ne pas multiplier les plugins « cosmétiques » reste une bonne idée.

En gros, si un plugin complexe ne sert qu’à un projet, il vaut mieux monter une instance Jenkins à part pour ce projet, plutôt que d’essayer d’avoir un seul Jenkins monolithique avec tous les plugins qui répondent à tous les besoins de toutes les équipes.

La fiabilité est à géométrie variable. On en est à une époque où un plugin, donc un truc qui est supposé être un minimum isolé du serveur devrait pas tout planter, qui en plus est désinstallé depuis, provoque une glorieuse exception sur l’écran des settings quand je clique sur save et sur l’écran de réglage des prios des jobs. Alors ok, qu’un plugin moisi fasse des dégâts dans son coin, je veux bien, mais qu’un plugin réussisse à impacter des fonctionnalités de base d’administration d’un serveur Jenkins, c’est que c’est codé avec le cul.

Dans un monde parfait, j’aurais un serveur de test des mises à jour des serveurs d’ic, mais en ce moment on est charette niveau ressources.

Je serais curieux de savoir quel est le coupable une fois que tu l’auras trouvé.

Multi Branch Priority Sorter.
En fait, j’avais besoin de pouvoir mettre une prio supérieure à la branche master, qui est la source de mon livrable de prod, par rapport aux branches pour les devs en cours. Et je voulais pas faire un Jenkinsfile custom spécifique à la branche master, ou m’embêter avec autre chose qu’un multibranch pipeline.
Je suspecte qu’il a corrompu, entre autres, une partie de la conf de « Priority Sorter Plugin ». Ce qui voudrait dire que les plugins sont mal isolés les uns des autres en plus d’être mal isolés du core.

Mais sinon oui, tu as raison et j’aurais clairement du regarder le nombre d’installs de ce plugin de chie.

Je serai toi, je regarderais Jenkins X si tu dois donner un effet wow. Cela dit, c’est une grosse marché niveau connaissance si tu connais peu docker… Il va te falloir comprendre vite les bases de docker puis de kubernetes. Mais ça te donne des projets clés en mains, de gitlab jusqu’au déploiement sur kubernetes.

Mais… C’est vraiment pas une première étape. Ça embarque une assez grosse stack technique, mais c’est vraiment bien pensé et ça tourne au poil.

Intéressant, mais le truc c’est que l’application bancaire est une gigantesque usine à gaz qui, pour le moment, ne tourne que sur des OS bien précis, sur des containers ça ne marchera jamais. Je pense que je vais la jouer safe, comme vous me le conseillez, je vais « juste » installer Docker sur mon laptop Windows, instancier Jenkins et GitLab dedans, créer un projet Java, le hoster dans GitLab et le lancer via Jenkins. Ce sera déjà sympa comme présentation, je pense :slight_smile: Il manquera juste le côté « release automation ». Si j’avance assez vite sur le reste (et sur les slides) je me pencherai un peu là-dessus.

Ça c’est plutôt pour faire de la veille technologique. Le but de Jenkins X, à l’origine, chez Cloudbees, c’est de rendre scalable et cloisonnables les builds de leurs clients. C’est complexe à mettre en œuvre, et c’est pas vraiment sec.

Tu peux techniquement faire ça. Et pour un prototype ça va marcher. Mais c’est une plutôt mauvaise idée pour débuter parce que ça va te pousser à plein de mauvaises pratiques qui vont devenir des mauvaises habitudes.

S’il y a trois bonnes pratiques à retenir avec les conteneurs, pour éviter de les rendre inexploitables en production, ce sont celles-ci :

  1. un conteneur = un processus (PID 1 dans le conteneur) => pour s’assurer que le cycle de vie du conteneur correspond au cycle de vie du processus (dit autrement, le démon Docker ne s’occupe pas pas les autres processus que 1, et tu peux avoir un conteneur qui a l’air sain alors que ses processus !=1 sont en vrac) ;
  2. idempotence => un conteneur c’est un FS immutable + des volumes ciblés qui contiennent les données persistantes ; on doit pouvoir détruire et recréer un conteneur (et pas juste l’arrêter/redémarrer) sans que ça soit incompatible avec l’état des données dans les volumes
  3. on privilégie d’écrire toutes les logs sur la sortie standard du conteneur (process d’id 1) => on peut aussi mettre dans un volume, mais c’est une mauvaise pratique parce qu’il faut alors surveiller la croissance du volume ; alors que les logs sur la sortie standard peuvent être consommées par un driver approprié pour être déversées dans un outil comme ELK etc.

Encore une fois pour un prototype ça n’a pas grande importance. Mais du coup le prototype n’aura guère de valeur parce qu’il ne ressemblera absolument pas à ce qu’il faudra faire pour aller en production, même pas de loin.

Le point 3 est le plus simple à régler, il suffit de changer les configurations des loggers. Mais le point 2 entraîne pas mal de conséquences sur les performances (I/O dans un volume) et la sécurité (données confidentielles du conteneur dans des volumes). Jenkins et Gitlab sont de plutôt mauvais candidats à la conteneurisation à cause de ce point 2.

De mon expérience, Jenkins est probablement l’un des outils les plus difficiles à conteneuriser proprement pour qu’il soit exploitable dans des conditions de production. Gitlab c’est moins difficile, mais pas facile non plus (et de manière générale tout ce qui ressemble à une base de donnée c’est pas évident à conteneuriser).

Mon conseil pour un prototype où tu veux démontrer le fonctionnement des outils, tu fais ça soit dans une VM, soit même directement sur ton poste de dév.

1 « J'aime »
  • idempotence => un conteneur c’est un FS immutable + des volumes ciblés qui contiennent les données persistantes ; on doit pouvoir détruire et recréer un conteneur (et pas juste l’arrêter/redémarrer) sans que ça soit incompatible avec l’état des données dans les volumes
  • on privilégie d’écrire toutes les logs sur la sortie standard du conteneur (process d’id 1) => on peut aussi mettre dans un volume, mais c’est une mauvaise pratique parce qu’il faut alors surveiller la croissance du volume ; alors que les logs sur la sortie standard peuvent être consommées par un driver approprié pour être déversées dans un outil comme ELK etc.

Soit dit en passant, le fait de limiter le nombre de VMs stateful et d’éviter au maximum les logs sur disque local, ce sont simplement de bonnes pratiques d’administration système moderne, ça n’a rien de spécifique à l’intégration continue.

Oui, ce que je disais sur les conteneurs c’était généraliste, et pas limité au contexte CI/CD. Et si ce sont déjà des bonnes pratiques optionnelles pour les VM, ça devient des prérequis quasi-incontournables pour les conteneurs en production.