Hur man samlar projekt i Jenkins om man behöver många olika miljöer

Hur man samlar projekt i Jenkins om man behöver många olika miljöer

Det finns många artiklar på Habré om Jenkins, men få beskriver exempel på hur Jenkins och hamnarbetare arbetar. Alla populära projektbyggande verktyg som Drone.io, Bitbucket Pipeline, GitLab, GitHub-åtgärder och andra, kan samla allt i containrar. Men hur är det med Jenkins?

Idag finns det en lösning på problemet: Jenkins 2 är fantastisk att arbeta med Hamnarbetare. I den här artikeln vill jag dela med mig av min erfarenhet och visa hur du kan göra det själv.

Varför började jag lösa det här problemet?

Eftersom vi är i sällskap Citronium Eftersom vi använder många olika teknologier måste vi ha olika versioner av Node.JS, Gradle, Ruby, JDK och andra på monteringsmaskinen. Men ofta kan versionskonflikter inte undvikas. Ja, du kommer att ha rätt om du säger att det finns olika versionshanterare som nvm, rvm, men allt är inte så smidigt med dem och dessa lösningar har problem:

  • en stor mängd körtid som utvecklare glömmer att rengöra;
  • det finns konflikter mellan olika versioner av samma körtider;
  • Varje utvecklare behöver en annan uppsättning komponenter.

Det finns andra problem, men låt mig berätta om lösningen.

Jenkins i Docker

Eftersom Docker nu är väletablerat i utvecklingsvärlden kan nästan allt köras med Docker. Min lösning är att ha Jenkins i Docker och kunna köra andra Docker-containrar. Denna fråga började ställas redan 2013 i artikeln "Docker kan nu köras inom Docker".

Kort sagt, du behöver bara installera Docker själv i en fungerande behållare och montera filen /var/run/docker.sock.

Här är ett exempel på Dockerfile som visade sig för 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

Således fick vi en Docker-behållare som kan köra Docker-kommandon på värddatorn.

Bygg inställning

För inte så länge sedan fick Jenkins möjligheten att beskriva sina regler med hjälp av Pipeline syntax, vilket gör det ganska enkelt att ändra byggskriptet och lagra det i förvaret.

Så låt oss lägga in en speciell Dockerfil i själva arkivet, som kommer att innehålla alla bibliotek som behövs för bygget. På så sätt kan utvecklaren själv förbereda en repeterbar miljö och kommer inte behöva be OPS att installera en specifik version av Node.JS på värden.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Denna byggbild är lämplig för de flesta Node.JS-applikationer. Vad händer om du till exempel behöver en bild för ett JVM-projekt med en ekolodsskanner inkluderad? Du är fri att välja de komponenter du behöver för montering.

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/

Vi beskrev monteringsmiljön, men vad har Jenkins med det att göra? Och Jenkins-agenter kan arbeta med sådana Docker-bilder och bygga dem internt.

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"
    }
}

Direktiv agent använder egendom dockerdär du kan ange:

  • namnet på monteringsbehållaren enligt din namnpolicy;
  • argument som behövs för att köra byggbehållaren, där vi i vårt fall monterar den aktuella katalogen som en katalog inuti behållaren.

Och redan i byggstegen anger vi vilka kommandon som ska köras i Docker-byggagenten. Detta kan vara vad som helst, så jag startar även applikationsdistribution med ansible.

Nedan vill jag visa en generisk Jenkinsfil som en enkel Node.JS-applikation kan bygga.

def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""

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

    agent any

    stages {

        stage("Prepare build image") {
            steps {
                sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
            }
        }

        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"
            }
        }

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

}

Vad hände?

Tack vare denna metod löste vi följande problem:

  • konfigurationstiden för miljömontering reduceras till 10 - 15 minuter per projekt;
  • en helt repeterbar applikationsbyggande miljö, eftersom du kan bygga den på detta sätt på din lokala dator;
  • det finns inga problem med konflikter mellan olika versioner av monteringsverktyg;
  • alltid en ren arbetsyta som inte blir igensatt.

Själva lösningen är enkel och självklar och låter dig få vissa fördelar. Ja, ingångströskeln har stigit lite jämfört med enkla kommandon för sammanställningar, men nu finns det en garanti för att det alltid kommer att byggas och utvecklaren själv kan välja allt som är nödvändigt för hans byggprocess.

Du kan också använda bilden jag samlat in Jenkins + Docker. Alla källor är öppna och finns på rmuhamedgaliev/jenkins_docker.

När den här artikeln skrevs uppstod en diskussion om att använda agenter på fjärrservrar för att inte ladda huvudnoden med hjälp av en plugin docker-plugin. Men jag kommer att prata om detta i framtiden.

Källa: will.com

Lägg en kommentar