Comment construire des projets dans Jenkins, si de nombreux environnements différents sont nécessaires

Comment construire des projets dans Jenkins, si de nombreux environnements différents sont nécessaires

Il existe de nombreux articles sur Jenkins dans le blog Habr, mais peu décrivent un exemple de fonctionnement de Jenkins avec des agents Docker. Tous les outils de compilation de projets populaires tels que Drone.io, Bitbucket Pipeline, GitLab, GitHub actions et d'autres, peuvent tout compiler dans des conteneurs. Mais qu'en est-il de Jenkins ?

Aujourd'hui, il existe une solution au problème : Jenkins 2 sait parfaitement travailler avec des agents Docker. Dans cet article, je souhaite partager mon expérience et montrer comment vous pouvez le faire vous-même.

Pourquoi ai-je décidé de résoudre ce problème ?

Dans notre entreprise Citronium , nous utilisons de nombreuses technologies différentes, ce qui nécessite de maintenir différentes versions de Node.JS, Gradle, Ruby, JDK, etc., sur la machine de compilation. Mais il est souvent inévitable d'avoir des conflits de versions. Oui, vous aurez raison de dire qu'il existe différents gestionnaires de versions comme nvm, rvm, mais tout n'est pas si simple avec eux et ces solutions rencontrent des problèmes :

  • un grand volume de runtimes que les développeurs oublient de nettoyer ;
  • des conflits entre différentes versions de certains runtimes ;
  • chaque développeur a besoin de différents ensembles de composants.

Il y a d'autres problèmes, mais laissez-moi plutôt vous parler de la solution.

Jenkins dans Docker

Étant donné que Docker s'est bien établi dans le secteur du développement, presque tout peut être lancé avec Docker. Ma solution consiste à faire en sorte que Jenkins soit dans Docker et puisse exécuter d'autres conteneurs Docker. Cette question a été posée pour la première fois en 2013 dans l'article «Docker can now run within Docker«.

En résumé, il est nécessaire d'installer Docker dans le conteneur de travail et de monter le fichier. /var/run/docker.sock.

Voici un exemple de Dockerfile que j'ai obtenu pour Jenkins.

FROM jenkins/jenkins:lts

USER root

RUN apt-get update && 

apt-get -y install apt-transport-https 
     ca-certificates 
     curl 
     gnupg2 
     git 
     software-properties-common && 
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && 
add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") 
   $(lsb_release -cs) 
   stable" && 
apt-get update && 
apt-get -y install docker-ce && 
usermod -aG docker jenkins

RUN curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose 

RUN apt-get clean autoclean && apt-get autoremove —yes && rm -rf /var/lib/{apt,dpkg,cache,log}/

USER jenkins

Ainsi, nous avons obtenu un conteneur Docker capable d'exécuter des commandes Docker sur la machine hôte.

Configuration de la compilation

Récemment, Jenkins a acquis la capacité de définir ses règles à l'aide de Pipeline syntaxe, ce qui permet de changer facilement le script de construction et de le stocker dans le référentiel.

Alors plaçons dans le référentiel un Dockerfile spécial, qui contiendra toutes les bibliothèques nécessaires à la construction. Ainsi, le développeur peut préparer un environnement reproductible sans avoir à demander à OPS de mettre une version spécifique de Node.JS sur l'hôte.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Cette image de construction convient à la plupart des applications Node.JS. Mais si vous avez besoin, par exemple, d'une image pour un projet JVM avec Sonar Scanner inclus ? Vous êtes libre de choisir les composants nécessaires à la construction.

FROM adoptopenjdk/openjdk12:latest

RUN apt update 
    && apt install -y 
        bash unzip wget

RUN mkdir -p /usr/local/sonarscanner 
    && cd /usr/local/sonarscanner 
    && wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-linux.zip 
    && unzip sonar-scanner-cli-3.3.0.1492-linux.zip 
    && mv sonar-scanner-3.3.0.1492-linux/* ./ 
    && rm sonar-scanner-cli-3.3.0.1492-linux.zip 
    && rm -rf sonar-scanner-3.3.0.1492-linux 
    && ln -s /usr/local/sonarscanner/bin/sonar-scanner /usr/local/bin/sonar-scanner

ENV PATH $PATH:/usr/local/sonarscanner/bin/
ENV SONAR_RUNNER_HOME /usr/local/sonarscanner/bin/

Nous avons décrit l'environnement de construction, mais quel est le lien avec Jenkins ? Les agents Jenkins peuvent travailler avec de telles images Docker et effectuer des constructions à l'intérieur.

stage("Build project") {
    agent {
        docker {
            image "project-build:${DOCKER_IMAGE_BRANCH}"
            args "-v ${PWD}:/usr/src/app -w /usr/src/app"
            reuseNode true
            label "build-image"
        }
    }
    steps {
        sh "yarn"
        sh "yarn build"
    }
}

Directive agent utilise la propriété docker, où vous pouvez spécifier :

  • le nom du conteneur de construction selon votre politique de nommage ;
  • les arguments nécessaires pour exécuter le conteneur de construction, où dans notre cas nous montons le répertoire actuel comme répertoire à l'intérieur du conteneur.

Et dans les étapes de construction, nous indiquons quelles commandes exécuter à l'intérieur de l'agent Docker de construction. Cela peut être n'importe quoi, de cette façon je lance également le déploiement d'applications avec Ansible.

Ci-dessous, je souhaite présenter un Jenkinsfile global, qui peut construire une simple application Node.JS.

def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""

pipeline { 
    options {
        buildDiscarder(
            logRotator(
                artifactDaysToKeepStr: "",
                artifactNumToKeepStr: "",
                daysToKeepStr: "",
                numToKeepStr: "10"
            )
        )
        disableConcurrentBuilds()
    }

    agent any

    stages {

        stage("Préparer l'image de construction") {
            steps {
                sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
            }
        }

        stage("Construire le projet") {
            agent {
                docker {
                    image "project-build:${DOCKER_IMAGE_BRANCH}"
                    args "-v ${PWD}:\/usr\/src\/app -w \/usr\/src\/app"
                    reuseNode true
                    label "build-image"
                }
            }
            steps {
                sh "yarn"
                sh "yarn build"
            }
        }

    post {
        always {
            step([$class: "WsCleanup"])
            cleanWs()
        }
    }

}

Qu'est-ce qui en est ressorti ?

Grâce à cette méthode, nous avons résolu les problèmes suivants :

  • le temps de configuration de l'environnement de construction est réduit à 10 à 15 minutes par projet ;
  • environnement de construction d'application entièrement reproductible, car il peut également être construit sur un ordinateur local ;
  • aucun problème de conflit entre différentes versions des outils de construction ;
  • espace de travail toujours propre, qui n'est pas encombré.

La solution elle-même est simple et évidente et permet d'obtenir uniquement des avantages. Oui, le seuil d'entrée a légèrement augmenté par rapport aux simples commandes de construction, mais maintenant il y a la garantie que la construction se fera toujours et le développeur peut choisir tout ce qui est nécessaire pour son processus de construction.

Vous pouvez également utiliser l'image que j'ai créée Jenkins + Docker. Tous les sources sont ouverts et se trouvent sur rmuhamedgaliev\/jenkins_docker.

Au cours de la rédaction de l'article, une discussion a eu lieu sur l'utilisation d'agents sur des serveurs distants afin de ne pas surcharger le nœud maître à l'aide du plugin docker-plugin. Mais j'en parlerai plus tard.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster